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

本文介绍了一种使用分离链接实现散列表的方法,并提供了完整的C语言代码示例。文章详细讲解了如何创建散列表、插入、查找及删除元素的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

如图

这里写图片描述

创建分离链接散列表代码

#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;
} 

结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值