• 哈希表(散列)HashTable实现


      近期刷Leetcode发现凡是找字符串中反复字符或者数组中找反复数据的时候就不知道从何下手了。


      所以决定学习一下哈希表解题。哈希表的原理主要是解决分类问题,hash表是介于链表和二叉树之间的一种中间结构。

    链表使用十分方便,可是数据查找十分麻烦;二叉树中的数据严格有序,可是这是以多一个指针作为代价的结果。hash表既满足了数据的查找方便,同一时候不占用太多的内容空间。使用也十分方便。
      定义hash数据结构,我採用的解决冲突的方法是分离链接法。
      这里写图片描写叙述

    //单链表结构
    typedef struct listnode* position;
    typedef struct listnode* list;
    struct listnode{
        ElementType data;
        position next;
    };
    //hash表结构
    typedef struct hashtbl*  hashtable;
    struct hashtbl {
        int tablesize;
        list *thelists;
    };

    哈希散列函数index = key%tablesize

    index HashFunc(const ElementType key,int tablesize)
    {
        //unsigned int hashval = 0;
        //while(*key != '')   
            //hashval = (hashval << 5) + *key++;
        //return hashval % tablesize;
        return key % tablesize;
    }

    创建hash表,并初始化

    hashtable InitializeHashTable(int tablesize)
    {
        hashtable H;
        H = (hashtable)malloc(sizeof(hashtable));
        if(NULL == H) return NULL;
    
        H->tablesize = tablesize;
    
        H->thelists = (list*)malloc(sizeof(list) * H->tablesize);
        int i = 0;
        for(i=0;i<H->tablesize;i++)//链表是有表头的单链表
        {
            H->thelists[i] = (list)malloc(sizeof(struct listnode));
            H->thelists[i]->next = NULL;
        }
        return H;
    }

    删除hash表

    void DeleteHashTable(hashtable H)
    {
        position P,tem;
        int i = 0;
        for(i=0;i<H->tablesize;i++)
        {
            P = H->thelists[i]->next;
            while(P != NULL)
            {
                tem = P;
                free(tem);
                P=P->next;
            }
        }
        free(H->thelists);
        free(H);
    }

    往hash表中插入新元素

    position Find(ElementType key,hashtable H)
    {
        position P;
        list L;
        L = H->thelists[ HashFunc( key, H->tablesize) ];
        P = L->next;
        while(P != NULL && P->data != key)
            P = P->next;
    
        return P;
    }
    
    void Insert(ElementType key,hashtable H)
    {
        position pos,newnode;
        list L;
        pos = Find(key,H);
        if(pos == NULL)
        {
            newnode = (position)malloc(sizeof(position));
            L = H->thelists[ HashFunc( key, H->tablesize) ];
            newnode->data = key;
            newnode->next = L->next;
            L->next = newnode;
        }
    }

    打印hash表中全部的元素

    void PrintHashTable(hashtable H)
    {
        position P;
        int i = 0;
        for(i=0;i<H->tablesize;i++)
        {
            P = H->thelists[i]->next;
            printf("H->thelists[%d] = ",i);
            while(P != NULL)
            {
                printf("  %d",P->data);
                P=P->next;
            }
            printf("
    ");   
        }
    }

    測试main函数

    int main()
    {
        int num[10] = {3,45,5,64,7,9,8,3,75,75};
        hashtable H;
        H = InitializeHashTable(10);
        int i = 0;
        for(i=0;i<10;i++)
        {   
            Insert(num[i],H);
        }
        PrintHashTable(H);
        DeleteHashTable(H);
    }

    头文件

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    typedef int ElementType;
    typedef unsigned int index;

    測试结果。能够看到图片中散列后在hash表中一样位置的都保存下来了,形成一个链表如数据75 5 45;可是同样的数据仅仅保存一份,比方3和3,75和75
    这里写图片描写叙述
    这里写图片描写叙述

  • 相关阅读:
    map按照值排序
    结构体的三种排序方式
    归并排序
    数组模拟双向链表
    二刷斐波那契高精度
    2019年9月训练(贰)区间DP (luogu 4290)
    2019年9月训练(壹)数位DP (HDU 2089)
    2019年8月训练(贰)
    2019年8月训练(壹)二分,三分
    2019年7月训练(柒)
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7298589.html
Copyright © 2020-2023  润新知