Round19—hash查找

知识点:

知道什么是哈希查找,知道什么情况下产生冲突,知道产生冲突之后的解决方法有几种

选择题:

2-1散列冲突可以被描述为: (1分)

  • 两个元素除了有不同键值,其它都相同
  • 两个有不同数据的元素具有相同的键值
  • 两个有不同键值的元素具有相同的散列地址
  • 两个有相同键值的元素具有不同的散列地址

解析:冲突就是两个数据元素经过hash函数计算得到的hash值相同,也就是不同键值的元素具有相同的散列地址。

2-2将10个元素散列到100000个单元的哈希表中,是否一定产生冲突? (1分)

  • 一定会
  • 可能会
  • 一定不会
  • 有万分之一的可能会

解析:根据hash的原理我们知道可能会产生冲突。

2-3设散列表的地址区间为[0,16],散列函数为H(Key)=Key%17。采用线性探测法处理冲突,并将关键字序列{ 26,25,72,38,8,18,59 }依次存储到散列表中。元素59存放在散列表中的地址是: (2分)

  • 8
  • 9
  • 10
  • 11

解析:线性探测就是pos=(H(key)+i)%17,之要产生冲突i就从1开始取值,直到找到索引pos对应位置为空停止。

2-4采用线性探测法解决冲突时所产生的一系列后继散列地址: (1分)

  • 必须大于等于原散列地址
  • 必须小于等于原散列地址
  • 可以大于或小于但不等于原散列地址
  • 对地址在何处没有限制

解析:因为散列地址是为了将元素放置在数组里面,显然第三个是对的。

2-5将元素序列{18,23,11,20,2,7,27,33,42,15}按顺序插入一个初始为空的、大小为11的散列表中。散列函数为:H(Key)=Key%11,采用线性探测法处理冲突。问:当第一次发现有冲突时,散列表的装填因子大约是多少? (3分)

  • 0.27
  • 0.45
  • 0.64
  • 0.73

解析:装填因子就是列表当中已有的元素个数/列表的长度。

2-6给定散列表大小为11,散列函数为H(Key)=Key%11。按照线性探测冲突解决策略连续插入散列值相同的4个元素。问:此时该散列表的平均不成功查找次数是多少? (2分)

  • 1
  • 4/11
  • 21/11
  • 不确定

解析:因为连续插入4个相同的元素,并且查找不成功就是找到空位置就认定为元素不存在(因为采用的是线性探测),因此我们知道总次数N=5+4+3+2+7*1,因此平均就是21/11.

2-7从一个具有N个结点的单链表中查找其值等于X的结点时,在查找成功的情况下,需平均比较多少个结点? (2分)

  • N/2
  • N
  • (N−1)/2
  • (N+1)/2

解析:总次数是N*(N+1)/2,那么评均显然是第四个是正确的。

2-8若N个关键词被散列映射到同一个单元,并且用分离链接法解决冲突,则找到这N个关键词所用的比较次数为:(2分)

  • N(N+1)/2
  • N(N−1)/2
  • N+1
  • N

解析:这个时候就是单链表的元素查找计算。

2-9给定散列表大小为17,散列函数为H(Key)=Key%17。采用平方探测法处理冲突:h​i​​(k)=(H(k)±i​2​​)%17将关键字序列{ 6, 22, 7, 26, 9, 23 }依次插入到散列表中。那么元素23存放在散列表中的位置是:(3分)

  • 0
  • 2
  • 6
  • 15

解析:根据散列函数,以及平方探测的方法我们可以知道第二个是对的。

2-10给定散列表大小为17,散列函数为H(Key)=Key%17。采用平方探测法处理冲突:h​i​​(k)=(H(k)±i​2​​)%17将关键字序列{ 23, 22, 7, 26, 9, 6 }依次插入到散列表中。那么元素6存放在散列表中的位置是:(3分)

  • 15
  • 10
  • 6
  • 2

解析:跟上面哪一个没有任何区别,就是两个数不一样。

2-11将元素序列{18, 23, 4, 26, 31, 33, 17, 39}按顺序插入一个初始为空的、大小为13的散列表中。散列函数为:H(Key)=Key%13,采用线性探测法处理冲突。问:当第一次发现有冲突时,散列表的装填因子大约是多少? (3分)

  • 0.54
  • 0.63
  • 0.31
  • 0.62

解析:同之前的题目。

2-12给定散列表大小为11,散列函数为H(Key)=Key%11。按照线性探测冲突解决策略连续插入散列值相同的5个元素。问:此时该散列表的平均不成功查找次数是多少?(2分)

  • 26/11
  • 5/11
  • 1
  • 不确定

解析:同之前的题目。

函数题:

6-1 线性探测法的查找函数 (20分)

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

函数接口定义:

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.

AC代码:

Position Find(HashTable H, ElementType Key)
{
    Position pos = Hash(Key, H->TableSize);
    Position cur_pos = pos;
    if(H->Cells[pos].Info == Legitimate && H->Cells[pos].Data == Key)
        return pos;
    int num_of_conflict = 0;
    while(H->Cells[cur_pos].Info != Empty && H->Cells[cur_pos].Data != Key)
    {
        num_of_conflict++;
        if(num_of_conflict == H->TableSize)
            return ERROR;
        cur_pos = (pos + num_of_conflict) % H->TableSize;
    }
    return cur_pos;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值