假设有一个30人的班级,用汉语拼音表示学生姓名,要求以学生姓名为关键字设计一个哈希表,采用除留余数法构造哈希函数,用线性探测再散列法处理冲突,平均查找长度上限为2。并且按姓名在哈希表中查询学生的位置和
时间: 2023-04-25 15:04:16 浏览: 230
对于这个班级的学生姓名,我们可以用拼音表示,例如:
zhāng sān, lǐ sì, wáng wǔ, zhào liù, chén qī, ...
接下来,我们需要设计一个哈希表,以学生姓名为关键字。我们可以选择除留余数法作为哈希函数,例如:
hash(name) = sum(ord(c) for c in name) % 30
其中,ord(c) 表示字符 c 的 ASCII 码值,sum 表示求和。这个哈希函数将学生姓名的 ASCII 码值相加,并对 30 取余,得到一个在 到 29 之间的整数,作为该学生在哈希表中的位置。
如果两个学生的姓名映射到同一个位置,就会发生冲突。为了处理冲突,我们可以采用线性探测再散列法。具体来说,如果第 i 个位置已经被占用,就尝试查找第 i+1, i+2, i+3, ... 个位置,直到找到一个空闲位置或者查找次数超过了哈希表的大小。如果查找次数超过了哈希表的大小,就说明哈希表已经满了,需要重新构建。
为了保证平均查找长度上限为 2,我们需要调整哈希表的大小和哈希函数。具体来说,我们可以选择一个质数作为哈希表的大小,例如 31,这样可以保证除留余数法的效果更好。同时,我们需要调整哈希函数,使得冲突的概率更小。例如,我们可以将哈希函数改为:
hash(name) = (sum(ord(c) for c in name) * 31 + ord(name[])) % 31
其中,ord(name[]) 表示姓名的第一个字符的 ASCII 码值,乘以 31 是为了增加随机性。这个哈希函数将学生姓名的 ASCII 码值相加,并乘以 31,再加上姓名的第一个字符的 ASCII 码值,最后对 31 取余,得到一个在 到 30 之间的整数,作为该学生在哈希表中的位置。
现在,我们可以按照学生姓名在哈希表中查询学生的位置。例如,如果要查询张三的位置,可以计算出 hash("zhāng sān") = 23,然后查找哈希表的第 23 个位置,如果该位置为空,就说明哈希表中不存在张三;如果该位置已经被占用,就需要进行线性探测,直到找到张三或者查找次数超过了哈希表的大小。如果查找次数超过了哈希表的大小,就说明哈希表中不存在张三。
阅读全文