哈希表

warning: 这篇文章距离上次修改已过424天,其中的内容可能已经有所变动。

将数组中每个元素对离数组长度len最近的素数取余获得哈希表的下标值,并使用头插法分配到哈希链表中,所以时间复杂度最坏为O(n),即数组中所有数的哈希下标都相等。

#include<iostream>
#include<cstdlib>
#include<cassert>
using namespace std;
 
#define N 12//元素数量为12
#define P (N+1)//离元素个数最近的素数为13
 
typedef struct HashNode{
    int data;//数据域
    HashNode* link;//指针域
}HashNode;
 
typedef HashNode* HashTable[P];//创建哈希数组,元素大小为P,类型为指针
 
void InitHt(HashTable &ht){
    for(int i=0;i<P;i++)
        ht[i]=NULL;
}//初始化哈希数组
 
int Hash(int x){
    return x%P;
}//计算元素的哈希值
 
void InsHt(HashTable &ht,int x){
    int index=Hash(x);//求出元素哈希下标
    HashNode* n=(HashNode*)malloc(sizeof(HashNode));//分配节点空间
    assert(n);
    n->data=x;//初始化节点值
    n->link=ht[index];
    ht[index]=n;//头插法插入新节点
}//哈希链表插入元素
 
void ShowHt(HashTable &ht){
    for(int i=0;i<P;i++){
        cout<<i<<": ";
        HashNode* n=ht[i];
        while(n){//判断节点是否为空
            cout<<n->data<<"-->";
            n=n->link;
            //如果有冲突,则使当前节点n指向冲突的元素,否则指向空
        }
        cout<<"NULL"<<endl;
    }
}
 
HashNode* SearchHt(HashTable &ht,int x){
    int index=x%P;//通过哈希函数求关键字下标
    HashNode *n=ht[index];//n为当前哈希表中index位置链表指针
    while(n!=NULL&&n->data!=x){//相等则直接返回节点
        n=n->link;//不相等则指针右移查找下一节点
    }
    return n;//返回节点
}
 
bool RemoveHt(HashTable &ht,int x){
    HashNode* n=SearchHt(ht,x);
    if(!n)
        return false;//如果节点为空则返回false
    HashNode* pre;//要删除节点所在链表的首节点
    int index=Hash(x);
    pre=ht[index];//初始化首节点
    if(pre==n){//如果首节点即为要删除的节点
        ht[index]=pre->link;
        free(pre);
        return true;
    }
    while(pre->link!=n)//查找节点
        pre=pre->link;
    pre->link=n->link;//删除节点n
    free(n);
    return true;
}
 
int main(){
//    printf("%d",N);
//    printf("%d",P);
//  测试define常量
    HashTable ht;//哈希数组
    InitHt(ht);
    int arr[]={19,14,1,23,68,20,84,27,55,11,10,79};
    for(int i=0;i<N;i++)
        InsHt(ht,arr[i]);
    cout<<"哈希表如下:"<<endl;
    ShowHt(ht);
    cout<<endl;
    int x=19;
    HashNode* p=SearchHt(ht,x);
    if(p!=NULL){
        cout<<"查到该元素"<<endl;
    }
    else
        cout<<"不存在该元素"<<endl;
    x=27;
    if(RemoveHt(ht,x))
        cout<<"已删除节点"<<endl;
    else
        cout<<"删除失败"<<endl;
    cout<<"删除后哈希表如下"<<endl;
    ShowHt(ht);//验证删除操作是否成功
}

图1图1

图2图2

none
最后修改于:2023年11月25日 18:43

评论已关闭