实现哈希表的相关运算算法

/**
*    实验题目:
*        实现哈希表的相关运算算法
*    实验目的:
*        领会哈希表的构造和查找过程及其相关算法设计
*    实验内容:
*        设计程序,实现哈希表的相关运算,并完成如下功能:
*    1、建立关键字序列(16, 74, 60, 43, 54, 90, 46, 31, 29, 88, 77)对应的哈希
*    表A[0..12],哈希函数为H(k)=k%p,并采用开放地址法中的线性探测法解决冲突
*    备注:
*        这里的哈希表A[0..12],m=13,取p=m=13,哈希函数H(k)=k%13
*    解决冲突的线性探测法是:d(0)=H(k),d(i+1)=(d(i)+1)%m
*    2、在上述哈希表中查找关键字为29的记录
*    3、在上述哈希表中删除关键字为77的记录,再将其插入
*/

#include <stdio.h>

#define MAX_SIZE (100)                                // 定义最大哈希表长度
#define NULL_KEY (-1)                                 // 定义空关键字值
#define DEL_KEY  (-2)                                 // 定义被删关键字值

typedef int key_type;                                 // 关键字类型
typedef char info_type;                               // 其他数据类型
typedef struct {
    key_type key;                                     // 关键字域
    info_type data;                                   // 其他数据域
    int det_times;                                    // 探测次数域
}HashTable;                                           // 哈希表元素类型

/*---------------将关键字为key的记录插入到哈希表中-------------*/
void insert_ht(HashTable ha[], int &n, int m, int p, key_type key)
{
    int i;
    int adr;

    adr = key % p;
    if(ha[adr].key == NULL_KEY || ha[adr].key == DEL_KEY)       // x[i]可以直接放在哈希表中
    {
        ha[adr].key = key;
        ha[adr].det_times = 1;
    }
    else                                                        // 发生冲突时采用线性探测法解决冲突
    {
        i = 1;                                                  // i记录x[i]发生冲突的次数
        do
        {
            adr = (adr + 1) % m;
            i++;
        }while(ha[adr].key != NULL_KEY && ha[adr].key != DEL_KEY);
        ha[adr].key = key;
        ha[adr].det_times = i;
    }
    n++;
}

/*---------------------------创建哈希表------------------------*/
void create_ht(HashTable ha[], key_type x[], int n, int m, int p)
{
    int i;
    int n1 = 0;

    for(i = 0; i < m; i++)                          // 哈希表置初值
    {
        ha[i].key = NULL_KEY;
        ha[i].det_times = 0;
    }

    for(i = 0; i < n; i++)
        insert_ht(ha, n1, m, p, x[i]);
}

/*---------------------------输出哈希表------------------------*/
void disp_ht(HashTable ha[], int n, int m)
{
    int i;
    float avg = 0;

    printf("  哈希表地址:   ");
    for(i = 0; i < m; i++)
    {
        printf("%-4d", i);
    }
    printf("\n");

    printf("  哈希表关键字:");
    for(i = 0; i < m; i++)
    {
        if(ha[i].key == NULL_KEY || ha[i].key == DEL_KEY)
        {
            printf("    ");
        }
        else
        {
            printf("% -4d", ha[i].key);
        }
    }
    printf("\n");

    printf("  探测次数:    ");
    for(i = 0; i < m; i++)
    {
        if(ha[i].key == NULL_KEY || ha[i].key == DEL_KEY)
        {
            printf("    ");
        }
        else
        {
            printf("% -4d", ha[i].det_times);
        }
    }
    printf("\n");

    for(i = 0; i < m; i++)
    {
        if(ha[i].key != NULL_KEY || ha[i].key != DEL_KEY)
        {
            avg = avg + ha[i].det_times;
        }
    }
    avg = avg / n;
    printf("  平均查找长度ASL(%d)=%g\n", n, avg);
}

/*---------------------------在哈希表中查找关键字key------------------------*/
int search_ht(HashTable ha[], int m, int p, key_type key)
{
    int adr;

    adr = key % p;
    while(ha[adr].key != NULL_KEY && ha[adr].key != key)
    {
        adr = (adr + 1) % m;                 // 采用线性探测法找下一个地址
    }

    if(ha[adr].key == key)                   // 查找成功
        return adr;
    else                                     // 查找失败
        return -1;
}

/*---------------------------删除哈希表中的关键字key------------------------*/
int delete_ht(HashTable ha[], int m, int p, int &n, int key)
{
    int adr;

    adr = search_ht(ha, m, p, key);
    if(adr != -1)                       // 在哈希表中找到该关键字
    {
        ha[adr].key = DEL_KEY;
        n--;                            // 哈希表长度减1
    }
    else                                // 在哈希表中未找到该关键字
        return 0;
}

int main(int argc, char *argv[])
{
    int x[] = {16,74,60,43,54,90,46,31,29,88,77};
    int n = 11;                             // 哈希表长度
    int m = 13;
    int p = 13;
    int key = 29;                           // 查找关键字
    int i;
    HashTable ha[MAX_SIZE];

    printf("(1)创建哈希表\n");
    create_ht(ha, x, n, m, p);
    printf("(2)输出哈希表:\n");
    disp_ht(ha, n, m);
    printf("(3)查找关键字为%d的记录位置\n", key);
    i = search_ht(ha, m, p, key);
    if(i != -1)
        printf("   ha[%d].key=%d\n", i, key);
    else
        printf("   提示:未找到%d\n", key);

    key = 77;
    printf("(4)删除关键字%d\n", key);
    delete_ht(ha, m, p, n, key);
    printf("(5)删除后的哈希表:\n");
    disp_ht(ha, n, m);
    printf("(6)查找关键字为%d的记录位置\n", key);
    i = search_ht(ha, m, p, key);
    if(i != -1)
        printf("   ha[%d].key=%d\n", i, key);
    else
        printf("   提示:未找到%d\n", key);
    printf("(7)插入关键字%d\n", key);
    insert_ht(ha, n, m, p, key);
    printf("(8)插入后的哈希表:\n");
    disp_ht(ha, n, m);


    return 0;
}
测试结果:

(1)创建哈希表
(2)输出哈希表:
  哈希表地址:   0   1   2   3   4   5   6   7   8   9   10  11  12
  哈希表关键字: 77      54  16  43  31  29  46  60  74  88      90
  探测次数:     2       1   1   1   1   4   1   1   1   1       1
  平均查找长度ASL(11)=1.36364
(3)查找关键字为29的记录位置
   ha[6].key=29
(4)删除关键字77
(5)删除后的哈希表:
  哈希表地址:   0   1   2   3   4   5   6   7   8   9   10  11  12
  哈希表关键字:         54  16  43  31  29  46  60  74  88      90
  探测次数:             1   1   1   1   4   1   1   1   1       1
  平均查找长度ASL(10)=1.5
(6)查找关键字为77的记录位置
   提示:未找到77
(7)插入关键字77
(8)插入后的哈希表:
  哈希表地址:   0   1   2   3   4   5   6   7   8   9   10  11  12
  哈希表关键字: 77      54  16  43  31  29  46  60  74  88      90
  探测次数:     2       1   1   1   1   4   1   1   1   1       1
  平均查找长度ASL(11)=1.36364
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值