雜湊表應用

拾憶熠發表於2020-10-25

雜湊表
以下程式碼用開雜湊裡的拉鍊法解決雜湊衝突

#include <iostream>
#include <string.h>
using namespace std;

#define hashsize 3
struct movietype
{
    char mname[20];
    int time;
};	
struct Node{
    char* key;//一個關鍵值,存放的是指向char型別字串的首地址
    Node* next;//指標
};
class hashtable
{
    private:
        Node* node[hashsize];//hashsize需要自定義
    public:
        hashtable();//初始化雜湊表
        ~hashtable();
        unsigned int hasha(char * key);//返回值型別是unsigned int ,形參是一個字串的首地址
        Node* lookup(char * key);//查詢函式
        bool insert(char * key);//插入函式
        void display();
};	
hashtable::hashtable()
{
    for(int i=0;i<hashsize;i++)
        node[i]=NULL;
        cout<<"建表成功!"<<endl;
}
hashtable::~hashtable(){}
unsigned int hashtable::hasha(char *key)
{
    unsigned int h=0;
    for(;*key;++key)
    {
        h=h*33 + *key;
    }
    //cout<<h % hashsize<<endl;
    return h % hashsize;
}
Node* hashtable::lookup(char * key)
//查詢函式,先計算出hasha的值,根據頭結點去根據指標找結點,不成功則返回null,成功則返回這個結點的指標
{
    Node * np;
    unsigned int n;
    n=hasha(key);
    int a;
    np=node[n];
    while(np!=NULL)
    {   
        if(! strcmp(key,np->key))//strcmp函式,相等返回0,小於(前面的字串開頭那個字母小於後面那個開頭字母)返回負數,
            {cout<<"success:頭結點不為空,進入連結串列查詢"<<"結點值為:"<<np->key<<endl;
            return np;}//找到了
            np=np->next;
    }
    //cout<<"沒找到該節點!"<<endl;
    return NULL;
}
bool hashtable::insert(char * key)
//插入函式,首先要查詢是不是存在,存在的話返回false,不存在的話插入
{
    Node* np;
    unsigned int n;
    if(np=lookup(key)) //找到了
    {
        cout<<"已經存在該節點!"<<endl;
        return false;
    }
    else //未找到,插入,
        {
            n=hasha(key);
            //np = (Node*)malloc(sizeof(Node));//分配一個Node
            np=new Node;
            np->key=key;//先把np的key和形參聯絡起來
            
            if(node[n]==NULL)
                {
                    node[n] = np;//頭結點為空,直接把node[n]賦值為np
                    node[n]->next=NULL;//頭結點下一個結點為空
                }
            else
            {
                np->next=node[n]->next;
                node[n]->next=np;
                //node[n]->next=np;
                //np = node[n]->next;
                //錯誤的兩行
            }
            //cout<<"插入成功!"<<endl;
            return true;
        }
    return true;
}

void hashtable::display(){
	Node* temp;
	for (int i = 0; i < hashsize; ++i)//迴圈node結點
	{
		if(!node[i]){
			cout<<i<<"[]"<<endl;//空
		}else{
		    temp=node[i];
		    while(temp!=NULL)
		    {
		        cout<<i;
		        cout<<"["<<temp->key<<"]";
		        temp=temp->next;
		    }
		cout<<endl;
		}
	}
}


int main() {
    int i;
    
    hashtable *ht=new hashtable();
    
    movietype waitingm; 
    movietype movie[]=
    {
        {"我和我的祖國",126},
        {"我和我的家鄉",145},
        {"征途",106},
        {"姜子牙",122}
    };
    for(i=0;i<4;i++)
    {
        char *arr =movie[i].mname;
        ht->insert(arr);
    }
    ht->display();
	cout<<"input:"<<endl;
	char in[20];
	cin>>in;
	char* w;
	w=in;
	//char* w="征途";
    ht->lookup(w);
	if(ht->lookup(w))//找到結點,輸出它的其他資訊
	    {
	        for(i=0;i<4;i++)
	            if(!strcmp(movie[i].mname,w))
	                waitingm=movie[i];
	                cout<<waitingm.time;
	    }
    
	return 0;
}

輸出結果

相關文章