建立哈希表并进行插入删除查找元素操作

注意:
1.本博客仅供参考交流使用,请读者务必自行实践,切勿生搬硬套
2.由于笔者水平有限,若文中有错误或者可以改进之处,欢迎在评论区指出

题目
Description

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

本题请使用散列函数:除留余数法(取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址)建立哈希表,并判断给定值是否在散列表中。

注意:本题请考虑冲突情况,即碰撞。本题请使用链冲突法解决冲突,即散列到相同地址后以建立子链的方式解决元素冲突,因此本题不考虑总元素大于散列表大小而溢出的情况。重复元素只存一个。

Input
第一行数字表示要建立的散列表的大小,第二行表示要作为元素建立散列表的整数序列(注意:元素之间以空格分开,第一行散列表大小并不表示本行元素的数量),第三行表示要插入元素的数量n,接下来n行表示待插入元素值;下一行表示要删除元素的数量m,接下来m行表示待删除元素值;下一行表示要查找元素的数量r,接下来r行表示待查找元素值。

Output
插入无输出,对于每个待删除元素,元素若在散列表中,删除即可,若不在则输出 ‘Delete Error’,注意单词间空格;执行完插入删除后,查找元素是否在散列表中,若在则在相应行输出True, 否则输出False。

Sample Input 1

5
6 9 88 20 5 6
3
4
5
10
3
11
88
10
2
6
10

Sample Output 1

Delete Error
True
False
Hint

注意:总元素数量可能会超过散列表大小。本题请使用链冲突法解决冲突,即散列到相同地址后以建立子链的方式解决元素冲突,因此本题不考虑总元素大于散列表大小而溢出的情况。重复元素只存一个。

分析:这次尝试写在注释里(注释位置不严谨,只说明用)

# -*- coding: utf-8 -*-


class Slot(object):
    def __init__(self, key=None, next_slot=None):
        self.key, self.next_slot = key, next_slot
    # Slot是放key的槽
    
    
class HashTable(object):
    def __init__(self, size=10):
        self._table = [Slot()] * size
        self.size = size
    # 注意这里的_table,其实是在列表里放了同一个对象的size个引用,本质上只有一个空槽 
    
    def find_key(self, key):
        return key % self.size
    # 散列函数

    def append(self, key):
        index = self.find_key(key)
        temp_slot = self._table[index]
        if temp_slot.key is not None:
            if key != temp_slot.key:
                while temp_slot.next_slot is not None and key != temp_slot.next_slot.key:
                    temp_slot = temp_slot.next_slot
                if temp_slot.next_slot is None:
                    temp_slot.next_slot = Slot(key)
        else:
            self._table[index] = Slot(key)
        # 这里面的逻辑请读者自己理顺,要强调的是Slot(key)这句就补足了前文说的本质上只有一个空槽

    def __delitem__(self, key):
        index = self.find_key(key)
        temp_slot = self._table[index]
        if temp_slot.key is not None:
            if key != temp_slot.key:
                while temp_slot.next_slot is not None and key != temp_slot.next_slot.key:
                    temp_slot = temp_slot.next_slot
                if temp_slot.next_slot is not None:
                    temp_slot.next_slot = temp_slot.next_slot.next_slot
                else:
                    if key != temp_slot.key:
                        print('Delete Error')
                    else:
                        temp_slot.key = None
            else:
                if temp_slot.next_slot is not None:
                    self._table[index] = temp_slot.next_slot
                else:
                    temp_slot.key = None
        else:
            print('Delete Error')
        # 删除的逻辑和加入的逻辑是相似的,要注意删除每列第一个时的情况,然后__delitem__是为了可以这么写 del ...    
        
    def __contains__(self, key):
        index = self.find_key(key)
        temp_slot = self._table[index]
        if temp_slot.key is not None:
            if key != temp_slot.key:
                while temp_slot.next_slot is not None and key != temp_slot.next_slot.key:
                    temp_slot = temp_slot.next_slot
                if temp_slot.next_slot is not None:
                    return True
                else:
                    if key != temp_slot.key:
                        return False
                    else:
                        return True
            else:
                return True
        else:
            return False
        # 只要把del的del语句换成对或者否就可以了 __contains__是为了可以这样 if key in ...

    @property
    def table(self):
        return self._table
    # @property 让table变成一个属性来着,我们就可以这样: h.table[1].key = ... 或者 h.table = ...

    def traverse(self):
        for i in range(self.size):
            temp_slot = self.table[i]
            while temp_slot is not None:
                if temp_slot.key is not None:
                    print('self.table[', i, '].key is ', temp_slot.key)
                temp_slot = temp_slot.next_slot
    # 这个遍历很简单,目的是为了写程序时方便观察调试


n = int(input())

h = HashTable(n)

temp = list(map(int, input().split(" ")))

for i in range(len(temp)):
    h.append(temp[i])

m = int(input())

for i in range(m):
    h.append(int(input()))

k = int(input())

for i in range(k):
    del h[int(input())]

p = int(input())

for i in range(p):
    u = int(input())
    if u in h:
        print('True')
    else:
        print('False')

你可能感兴趣的:(python)