2012-09-27 42 views
-3

下面是我的代碼
創建具有鍵爲char *和值作爲函數指針散列表用戶定義的哈希表

// hash1.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 


#include <iostream> 
#include <cstdlib> 
#include <cstring> 
#include <iomanip> 
#define SIZE_KEY  16 
#define SIZE_VALUE1 64 
#define SIZE_VALUE2 16 
#define DEFAULT_TABLESIZE 101 
using namespace std; 
typedef void (*FunctionPtr)(); 
typedef void (*FunctionPtr1)(); 
void (*FunctionPtr2)(); 

    void ping(){ 
    cout<<"hello"; 
    } 
    void refresh(){ 
    cout<<"refresh"; 
    } 

typedef struct NODE 
{ 
    NODE(char* Key1,FunctionPtr func_ptr) 
    { 


     strcpy_s(Key,Key1); 
     FunctionPtr1 func_ptr1; 
     func_ptr1=func_ptr; 

     next = NULL; 
    } 
    NODE(){ 
    } 
    char Key[SIZE_KEY]; 
    FunctionPtr1 func_ptr1[SIZE_VALUE1]; 
    NODE *next; 
}; 

class Hashtable 
{ 
    private: 
     int table_size; 
     NODE** table; 
     int size; 
     long hashString(char* Key); 
     NODE* find(char* Key); 
     NODE* current_entry; 
    public: 
     int current_index; 
     Hashtable(int T = DEFAULT_TABLESIZE);//constructor 
     virtual ~Hashtable();//destructor 
     bool put(NODE *); 
     bool get(NODE *); 
     bool contains(char* Key); 
     void removeAll(); 
     int getSize(); 
     void initIterator(); 
     bool hasNext(); 
     void getNextKey(char* Key); 
     friend void disp(NODE *); 
}; 

Hashtable::Hashtable(int T) 
{ 
    size = 0; 
    table_size = T; 
    table = new NODE*[table_size]; 
    for(int i=0; i<table_size; i++) 
    { 
     table[i] = NULL; 
    } 
} 

Hashtable::~Hashtable() 
{ 
    removeAll(); 
    delete[] table; 
} 

bool Hashtable::put(NODE *N) 
{//start put 
    if(find(N->Key) != NULL) 
    { 
     return false; 
    } 
    //NODE* entry = new NODE(N->Key ,*(FunctionPtr *)N->func_ptr1); 
    NODE* entry = new NODE(N->Key ,*(FunctionPtr *)N->func_ptr1); 
    int bucket = hashString(N->Key); 
    entry->next = table[bucket]; 
    table[bucket] = entry; 
    size++; 
    return true; 
}//end put 


bool Hashtable::get(NODE* N) 
{//start get 
    NODE* temp = find(N->Key); 
    if(temp == NULL) 
    { 
     *(FunctionPtr *)N->func_ptr1 = refresh; 
     return false; 
    } 
    else 
    { 
    *(FunctionPtr *)N->func_ptr1= *(FunctionPtr *)temp->func_ptr1; 

     return true; 
    } 
}//end get 

bool Hashtable::contains(char* Key) 
{//start contains 
    if(find(Key) == NULL) 
    { 
     return false; 
    } 
    else 
    { 
     return true; 
    } 
}//end contains 





void Hashtable::removeAll() 
{//start removeAll 
    for(int i=0; i<table_size; i++) 
    { 
     NODE* temp = table[i]; 
     while(temp != NULL) 
     { 
     NODE* next = temp->next; 
     disp(temp); 
     delete temp; 
     temp = next; 
     } 
    } 
    size = 0; 
}//end removeAll 

int Hashtable::getSize() 
{ 
    return size; 
} 

NODE* Hashtable::find(char* Key) 
{ //start find 
    int bucket = hashString(Key); 
    NODE* temp = table[bucket]; 
    while(temp != NULL) 
    { 
     if(strcmp(Key, temp->Key) == 0) 
     { 
     return temp; 
     } 
     temp = temp->next; 
    } 
    return NULL; 
}//end find 

long Hashtable::hashString(char* Key) 
{//start hashString 
    int n = strlen(Key); 
    long h = 0; 
    for(int i=0; i<n; i++) 
    { 
     //To get almost fair distributions of NODEs over the array 
     h = (h << 3)^Key[i]; 
    } 
    return abs(h % table_size); 
}//end hashString 

void Hashtable::initIterator() 
{//start initIterator 
    current_entry = NULL; 
    current_index = table_size; 
    for(int i=0; i<table_size; i++) 
    { 
     if(table[i] == NULL) 
     { 
      continue; 
     } 
     else 
     { 
     current_entry = table[i]; 
     current_index = i; 
     break; 
     } 
    } 
}//end initIterator 

bool Hashtable::hasNext() 
{ 
    if(current_entry == NULL) 
    { 
     return false; 
    } 
    else 
    { 
     return true; 
    } 
} 
void Hashtable::getNextKey(char* Key) 
{ 
    if(current_entry == NULL) 
    { 
     Key[0] = '\0'; 
     return; 
    } 
    strcpy(Key, current_entry->Key); 
    if(current_entry->next != NULL) 
    { 
     current_entry = current_entry->next; 
    } 
    else 
    { 
    for(int i=current_index+1; i<table_size; i++) 
    { 
     if(table[i] == NULL) 
     { 
      continue; 
     } 
     current_entry = table[i]; 
     current_index = i; 
     return; 
    } 
    current_entry = NULL; 
    current_index = table_size; 
    } 
} 

void dispAll(Hashtable* hashtable); 

int main() 
{ 
    char temp1[SIZE_KEY]; 
    Hashtable* hashtable = new Hashtable(); 

    NODE N1("1",ping); 
    if(!hashtable->contains(N1.Key)) 
    { 
     cout << "\nAdding NODE: "; 
     disp(&N1); 
     hashtable->put(&N1); 
    } 
// dispAll(hashtable); 


    strcpy(N1.Key, "314"); 
    *(FunctionPtr *) N1.func_ptr1=refresh; 

    if(!hashtable->contains(N1.Key)) 
    { 
     cout << "\nAdding NODE: "; 
     disp(&N1); 
     hashtable->put(&N1); 
    } 

/* strcpy(N1.Key, "320"); 
    *(FunctionPtr *) N1.func_ptr1= ping; 


    if(!hashtable->contains(N1.Key)) 
    { 
     cout << "\nAdding NODE: "; 
     disp(&N1); 
     hashtable->put(&N1); 
    } 

    strcpy(N1.Key, "768"); 
    *(FunctionPtr *)N1.func_ptr1= refresh; 
    if(!hashtable->contains(N1.Key)) 
    { 
     cout << "\nAdding node: "; 
     disp(&N1); 
     hashtable->put(&N1); 
    } 

    strcpy(N1.Key, "756"); 
*(FunctionPtr *) N1.func_ptr1= refresh; 

    if(!hashtable->contains(N1.Key)) 
    { 
     cout << "\nAdding node: "; 
     disp(&N1); 
     hashtable->put(&N1); 
    } */ 

    dispAll(hashtable); 

    // strcpy(temp1,"314"); 
    // hashtable->remove(temp1); 
    // cout << "\n\nAfter removing 314:" << endl; 
// dispAll(hashtable); 
    cout << "\n\nDestroying hashtable:" << endl; 
    delete hashtable; 
    return 0; 
} 


void disp(NODE *N1) 
{ 
cout << "\nKey:  " << N1->Key << "\nFunction " 
     << N1->func_ptr1 << endl; 
// FunctionPtr2(); 
} 



void dispAll(Hashtable *hashtable) 
{ 
    NODE N1; 
    cout << "\n\nCurrent nodes in hashtable:" << endl; 
    hashtable->initIterator(); 
    while(hashtable->hasNext()) 
    { 
     //cout<<"Current Index === "<<hashtable->current_index; 
     hashtable->getNextKey(N1.Key); 
     hashtable->get(&N1); 
     disp(&N1); 
    } 
} 

每個數據被寫入散列表VALUE時間cointains相同地址:( 我想特別功能,我將送地址..

+3

簡化您的代碼;你可能會自己找到答案! – Jaywalker

+0

難道你不能使用['std :: unordered_map'](http://en.cppreference.com/w/cpp/container/unordered_map)而不是創建你自己的散列表嗎? –

+0

掙扎從5小時:(.. ..沒有結果:( –

回答

0

有些問題可能是在struct NODE

typedef struct NODE 
{ 
    NODE(char* Key1,FunctionPtr func_ptr) 
    { 
     strcpy_s(Key,Key1); 
     FunctionPtr1 func_ptr1; // <-- Problem may be here 
     func_ptr1=func_ptr; 

     next = NULL; 
    } 
    NODE(){ 
    } 

    char Key[SIZE_KEY]; 
    FunctionPtr1 func_ptr1[SIZE_VALUE1]; // <-- And here 
    NODE *next; 
}; 

您在NODE::NODE(char*, FunctionPtr)中聲明瞭本地func_ptr1,並將參數func_ptr指定爲func_ptr1。因此,func_ptr被分配給本地變量,而不是成員變量。而且,一旦構造函數返回,就不會記住函數指針。
另一個問題:爲什麼是NODE::func_ptr1數組FunctionPtr1?我不認爲你打算在一個NODE實例中存儲多個函數指針。