解决散列表冲突问题-分离链接散列表

来源:互联网 发布:github ignore java 编辑:程序博客网 时间:2024/05/22 05:16

分离链接的做法是将同一个值的所有元素放到一个表中

如图

这里写图片描述

创建分离链接散列表代码

#include<stdio.h>#include<stdlib.h>typedef struct ListNode{    int Element;    struct ListNode *next;}List;typedef struct HashTb1{    int TableSize;    List *TheLists; }HashTable;//函数声明 HashTable InitializeTable(int TableSize);HashTable CreateHashTable(int Element, HashTable H);void PrintfHashTable(HashTable H); void FreeHashTable(HashTable H);int main(){    HashTable H;    int i;    int h[10] = {1, 0, 4, 16, 25, 64, 81, 9, 49, 36};    H = InitializeTable(10);    for(i = 0; i < 10; i++)    {        H = CreateHashTable(h[i], H);    }    PrintfHashTable(H);    FreeHashTable(H);    return 0;}HashTable InitializeTable(int TableSize){    HashTable H;    int i;    H.TableSize = TableSize;    //Allocate array of lists    H.TheLists = (List*) malloc(sizeof(List)*TableSize);    if(H.TheLists == NULL)    {        printf("Out of space !!");        exit(1);    }    for(i = 0; i < TableSize; i++)          //初始化散列表的表头     {        H.TheLists[i].next = NULL;        H.TheLists[i].Element = i;         //将表头元素定义为此表模值     }    return H;   }HashTable CreateHashTable(int Element, HashTable H){    int TempM, i;    //通过模运算找到合适的位置     TempM = Element % 10;    //动态创建List结构体     List *L = (List*)malloc(sizeof(List));    //将关键字存入相应的表中     for(i = 0; i < H.TableSize; i++)    {        if(H.TheLists[i].next == NULL)              //只有表头的情况         {            if(TempM == H.TheLists[i].Element)            {                H.TheLists[i].next = L;                L->Element = Element;                L->next = NULL;                return H;            }        }        else        {            if(TempM == H.TheLists[i].Element)     //表中已经有元素的情况,头插             {                L->next = H.TheLists[i].next;                H.TheLists[i].next = L;                L->Element = Element;                return H;                           }         }     }   }void PrintfHashTable(HashTable H){    int i;    List *L;    for(i = 0; i < H.TableSize; i++)    {        //先输出该行模         printf("%d   ", H.TheLists[i].Element);        if(H.TheLists[i].next != NULL)        {            L = H.TheLists[i].next;            do            {                printf("%d ",L->Element);                 L = L->next;            }while(L != NULL);        }        printf("\n\n");    }}void FreeHashTable(HashTable H){    int i;    List *L, *Tmp;    for(i = 0; i < H.TableSize; i++)    {        if(H.TheLists[i].next != NULL)        {            L = H.TheLists[i].next;            Tmp = H.TheLists[i].next;            do            {                free(L);                L = Tmp->next;                Tmp = L;            }while( L != NULL);                 }        free(H.TheLists);       }}

输出结果

这里写图片描述

创建好散列表之后,再添加一些后序操作,就比原来那个散乱无章的集合更容易实现功能。

Find 功能实现

void Find(int X, HashTable H){    int i;    int Tag = 0;    List *L;    for(i = 0; i < H.TableSize; i++)    {        if(H.TheLists[i].next != NULL)        {            L = H.TheLists[i].next;            do            {                if(L->Element == X)                {                    //输出被查找到的X的信息                     printf("%d is in the %d List , positon is %d\n", X, H.TheLists[i].Element, L);                    return;                }                L = L->next;            }while(L != NULL);              }    }    printf("Sorry, No Fund!\n");    return;}

结果
这里写图片描述

Insert函数实现
Insert的实现与创建散列表类似

HashTable Insert(int X, HashTable H){    int TempM, i;    //通过模运算找到合适的位置     TempM = X % 10;    //动态创建List结构体     List *L = (List*)malloc(sizeof(List));    //将关键字存入相应的表中 ,头插法     for(i = 0; i < H.TableSize; i++)    {        if(TempM == H.TheLists[i].Element)            {            L->next = H.TheLists[i].next;            H.TheLists[i].next = L;            L->Element = X;            return H;                       }    }}

结果

这里写图片描述

Delete操作

HashTable Delete(int X, HashTable H){    List *L;    List *Temp;    int i;    for(i = 0; i < H.TableSize; i++)    {        L = H.TheLists[i].next;        Temp = H.TheLists;        if(H.TheLists[i].next != NULL)        {            do            {                if(L->Element == X)                {                    Temp->next = L->next;                    free(L);                    return H;                }                Temp = L;                L = L->next;            }while(L != NULL);        }    }    printf("NO element to delete!\n");    return H;} 

结果

这里写图片描述

原创粉丝点击