哈希表(解决循环冲突链表问题)

  • 哈希表
    这里写图片描述
    哈希表是基于数组的顺序结构,每一个存储目标都会存在一个key值,哈希表也称为散列表。为解决冲突问题(多个目标用hash函数计算出相同的位置),本代码用了拉链法,另外本代码还解决了字符串插入哈希表循环冲突拉链的问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define  N 10 //哈希表链的数量(key值最大数)
// typedef int (*HASH_FUN)(const char* ch);

//定义hash表存储元素类型 我用了双向链表
typedef struct node
{   
    char ch_value[100];//存储query
    struct node * pre;//指向上一个节点指针
    struct node * cur;//每个hash_table[k]的尾指针
    //没有该指针 每次插入到对应的链都要从头到尾遍历,加入该指针,可解决循环冲突链表的问题
    struct node * next;//指向下一个节点
}node;

//初始化哈希表
node **  init_hash_table()
{
   node ** hash_table=(node **)malloc(N*sizeof(node*));
   int i;
   for(i=0;i<N;i++)
   {   
       hash_table[i]=NULL;
   }
    return hash_table;
}

//定义hash 函数 这里用字符串的ASCII来哈希
int  hash_fun(const char*  ch)
{
    int i;
    int sum=0;
    for(i=0;i<strlen(ch);i++)
    {
        sum+=ch[i];
    }
    return sum%N;
}

//把数据存入哈希表
void  save_hash_table(const char * ch,node** hash_table)
{   
    //初始化哈希表
    int key=hash_fun(ch);
    node*  ptr_new=(node*)malloc(1*sizeof(node));
    strcpy(ptr_new->ch_value,ch);
    ptr_new->pre=NULL;
    ptr_new->next=NULL;
    ptr_new->cur=NULL;

    node *ptr_head=hash_table[key];
    if(hash_table[key]==NULL)
    {   
        hash_table[key]=ptr_new;
        hash_table[key]->pre=NULL;
        hash_table[key]->cur=ptr_new;
        hash_table[key]->next=NULL;
    }
    else
    {         
        hash_table[key]->cur->next=ptr_new;
        ptr_new->pre=hash_table[key]->cur;
        hash_table[key]->cur=ptr_new;
        ptr_new->next=NULL;
        ptr_new->cur=NULL;      
    }
}

//查找函数
node * find_hash(const char * ch,node** hash_table)
{
    int key=hash_fun(ch);
    node * ptr_new=hash_table[key];
    if(hash_table[key]==NULL)
    {
        return NULL;
    }
    while(hash_table[key]!=NULL && ptr_new!=NULL)
    {
        int a=strcmp(hash_table[key]->ch_value,ch);
        if(a==0)
        {
            return ptr_new;
        }
        ptr_new=ptr_new->next;
    }
    return NULL;
}

//释放哈希表每条链
void free_hash(node ** hash_table)
{
    int i;
    for(i=0;i<10;i++)
    {
        node* ptr_move=hash_table[i];
        while(ptr_move!=NULL)
        {           
            node* ptr_tmp=ptr_move; 
            ptr_move=ptr_move->next;       
            free(ptr_tmp);
            ptr_tmp=NULL;
        }       

    }
}

删除函数(在删除函数中调用查找函数)
int delete_hash(const char * ch,node** hash_table)
{
    int key=hash_fun(ch);
    node * ptr_new=hash_table[key];
    node * ptr_tmp=find_hash(ch,hash_table);
    if(hash_table[key]==NULL || ptr_tmp==NULL)
    {
        printf("error\n");
        return 0;
    }
    if(ptr_tmp!=NULL)
    {
        if(ptr_new==ptr_tmp)
        {
            hash_table[key]=ptr_tmp->next;
            free(ptr_tmp);
            ptr_tmp=NULL;
        }
        else
        {
            while(ptr_new->next!=ptr_tmp)
            {
                ptr_new=ptr_new->next;
            }
            ptr_new->next=ptr_tmp->next;
            free(ptr_tmp);
            ptr_tmp=NULL;
            hash_table[key]->cur=ptr_new;
            ptr_new->next=NULL;
            ptr_new->cur=NULL;
        }
    }
}
//打印每条链上的数据
void  print_hash_table(node** hash_table)
{
    int i;
    for(i=0;i<N;i++)
    {   
        node* ptr_tmp=hash_table[i];
        printf("第%d条链:",i);
        if(ptr_tmp!=NULL)
        {
            while(ptr_tmp!=NULL)
            {
                printf("%s\t",ptr_tmp->ch_value);
                ptr_tmp=ptr_tmp->next;
            }
        }
        printf("\n");
    }
}

int main(int argc,const char* argv[])
{   
    node** hash_table=init_hash_table();
    save_hash_table("456456",hash_table);
    save_hash_table("sadashj",hash_table);
    save_hash_table("2dasd4",hash_table);
    save_hash_table("22222222",hash_table);
    save_hash_table("arrabh23fff",hash_table);
    save_hash_table("234",hash_table);
    save_hash_table("22",hash_table);
    save_hash_table("220",hash_table);
    save_hash_table("23",hash_table);
    save_hash_table("24",hash_table);
    save_hash_table("25",hash_table);
    save_hash_table("26",hash_table);
    save_hash_table("27",hash_table);
    save_hash_table("28",hash_table);
    save_hash_table("29",hash_table);
    save_hash_table("30",hash_table);
    save_hash_table("31",hash_table);
    save_hash_table("32",hash_table);
    save_hash_table("33",hash_table);

    // delete_hash("27",hash_table);
    print_hash_table(hash_table);

    if(find_hash("27",hash_table)!=NULL)//查找一个字符串
    {
        printf("find\n");
    }
    else
    {
        printf("not find\n");
    }

    free_hash(hash_table);//释放哈希表每条链
    return 0;
}

调用delete函数删除字符串“27”运行结果:
这里写图片描述

没有调用delete函数也就是没删除字符串“27”运行结果:
这里写图片描述

对比可得哈希表可任意删除和查找任意的字符串

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值