线性探测法的查找函数

试实现线性探测法的查找函数。

函数接口定义:

Position Find( HashTable H, ElementType Key );

其中HashTable是开放地址散列表,定义如下:

#define MAXTABLESIZE 100000  /* 允许开辟的最大散列表长度 */
typedef int ElementType;     /* 关键词类型用整型 */
typedef int Index;           /* 散列地址类型 */
typedef Index Position;      /* 数据所在位置与散列地址是同一类型 */
/* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */
typedef enum { Legitimate, Empty, Deleted } EntryType;

typedef struct HashEntry Cell; /* 散列表单元类型 */
struct HashEntry{
    ElementType Data; /* 存放元素 */
    EntryType Info;   /* 单元状态 */
};

typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode {   /* 散列表结点定义 */
    int TableSize; /* 表的最大长度 */
    Cell *Cells;   /* 存放散列单元数据的数组 */
};

函数Find应根据裁判定义的散列函数Hash( Key, H->TableSize )从散列表H中查到Key的位置并返回。如果Key不存在,则返回线性探测法找到的第一个空单元的位置;若没有空单元,则返回ERROR

裁判测试程序样例:

#include <stdio.h>

#define MAXTABLESIZE 100000  /* 允许开辟的最大散列表长度 */
typedef int ElementType;     /* 关键词类型用整型 */
typedef int Index;           /* 散列地址类型 */
typedef Index Position;      /* 数据所在位置与散列地址是同一类型 */
/* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */
typedef enum { Legitimate, Empty, Deleted } EntryType;

typedef struct HashEntry Cell; /* 散列表单元类型 */
struct HashEntry{
    ElementType Data; /* 存放元素 */
    EntryType Info;   /* 单元状态 */
};

typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode {   /* 散列表结点定义 */
    int TableSize; /* 表的最大长度 */
    Cell *Cells;   /* 存放散列单元数据的数组 */
};

HashTable BuildTable(); /* 裁判实现,细节不表 */
Position Hash( ElementType Key, int TableSize )
{
    return (Key % TableSize);
}

#define ERROR -1
Position Find( HashTable H, ElementType Key );

int main()
{
    HashTable H;
    ElementType Key;
    Position P;

    H = BuildTable(); 
    scanf("%d", &Key);
    P = Find(H, Key);
    if (P==ERROR)
        printf("ERROR: %d is not found and the table is full.\n", Key);
    else if (H->Cells[P].Info == Legitimate)
        printf("%d is at position %d.\n", Key, P);
    else
        printf("%d is not found.  Position %d is returned.\n", Key, P);

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例1:(注:-1表示该位置为空。下同。)

11
11 88 21 -1 -1 5 16 7 6 38 10
38结尾无空行

输出样例1:

38 is at position 9.



结尾无空行

输入样例2:

11
11 88 21 -1 -1 5 16 7 6 38 10
41

输出样例2:

41 is not found.  Position 3 is returned.

输入样例3:

11
11 88 21 3 14 5 16 7 6 38 10
41

输出样例3:

ERROR: 41 is not found and the table is full.

ANSWER

Position Find( HashTable H, ElementType Key ){
	int maxsize = H->TableSize;//表长
	int d = 0;//增量序列 
	Position p = Hash(Key,H->TableSize);//计算哈希值
	while(1){
		if(H->Cells[p].Info == Empty || H->Cells[p].Data == Key){//找到空位置或者对应值返回下标
			return p;
		}
		if(d < maxsize-1){
			d++;
		}else{
            break;
        }
		p = (Hash(Key,H->TableSize)+d)%maxsize;
	}
	return ERROR;
}
### PTA线性探测的原理与实现 #### 线性探测简介 哈希表是一种通过键值映射来存储和检索数据的数据结构。当发生冲突(即两个不同的键被映射到同一个位置)时,需要采用某种方解决这种冲突。线性探测就是一种常用的开放地址解决方案之一。 在线性探测中,如果某个位置已经被占用,则按照固定的步长顺序寻找下一个可用的位置。具体来说,假设初始哈希函数计算得到的位置为 `h`,则依次尝试访问 `h+1`, `h+2`, ..., `(h+k)%M` 的位置,直到找到目标或者遍历完整个表为止[^1]。 --- #### 查找函数的具体实现 以下是基于 C++ 的线性探测查找函数的实现: ```cpp Position Find(HashTable H, ElementType Key) { int x = Hash(Key, H->TableSize); // 初始哈希索引 int cnt = x; // 记录起始位置用于循环检测 if (H->Cells[x].Data == Key || H->Cells[x].Data == -1) { return x; } x++; while (x < H->TableSize && x != cnt) { // 防止无限循环 if (H->Cells[x].Data == Key) { return x; // 找到目标返回其索引 } if (H->Cells[x].Data == -1) { return x; // 如果遇到空槽位也返回该索引 } x++; x %= H->TableSize; // 循环回绕处理 } return ERROR; // 若未找到则返回错误标志 } ``` 上述代码实现了如下逻辑: - 使用给定的哈希函数计算出初始索引 `x`。 - 检查当前单元格是否为目标键或为空标记 `-1`,若是则直接返回当前位置。 - 否则进入循环逐步向后探查下一位置,并利用模运算 `%` 实现数组边界环绕功能。 - 设置计数器变量 `cnt` 来防止因重复探测而陷入死循环的情况[^2]。 --- #### 关于线性探测的优点与缺点 优点在于其实现简单高效,在理想情况下能够快速定位所需元素;然而它存在一些缺陷,比如容易引发聚集现象(Clustering),使得后续插入操作效率降低。因此实际应用时常会考虑其他更优策略如二次探测、双重散列等作为替代方案。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值