0%

【数据结构和算法】哈希表

数据结构之哈希表的介绍和代码实现


1 哈希表

1.1 介绍

  • 哈希表(Hash Table):也称为散列表,是根据key-value而直接进行访问的数据结构。通过key值快速映射到表中的一个位置来访问记录,以加快查找的速度。用来映射函数叫做散列函数,存放记录的数组叫做散列表

1.2 应用场景

1.3 实现思路

  • Hash表的实现思路和HashMap的底层相似
  • 通过数组 + 链表的形式来实现
  • 数组来存放链表,在添加一个数据的时候,通过散列函数对key进行一定的计算,确定数据的分区,然后在该分区以链表的形式添加数据

1.4 代码

  • 下面的代码只是简单的实现HashTable的添加数据 和 查找数据功能,还有很多细节没有写。例如重复的key名如何处理,修改数据,和删除数据等功能没有实现
  • (1)代码实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    public class HashTable {
    //子类 -- 链表结点
    private class Node {
    String key; //关键词
    Object value; //数据
    Node next; //下一个节点

    public Node(String key, Object value) {
    this.key = key;
    this.value = value;
    }

    @Override
    public String toString() {
    return '{' + key + ':' + value + '}';
    }
    }

    //---------------------------------------------------------------------
    //子类 -- 单链表
    private class LinkedList{
    Node headNode; //头结点

    /**
    * 添加数据(尾插法)
    * @param key 关键词
    * @param data 数据
    */
    public void add(String key, Object data) {
    Node node = new Node(key, data);

    //头结点没有数据,直接赋值给头结点
    if (headNode == null) {
    headNode = node;
    return;
    }

    Node temp = headNode;
    while (temp.next != null) {
    temp = temp.next;
    }
    temp.next = node;
    }

    /**
    * 通过关键词获取数据
    * @param key 关键词
    * @return Object
    */
    public Object get(String key) {
    //头结点为null,链表没数据
    if (headNode == null) {
    System.out.println("该数据不存在!");
    return null;
    }

    //遍历链表,寻找与key相同的数据
    Node temp = headNode;
    while (temp != null) {
    if (temp.key.equals(key)) {
    return temp.value;
    }
    temp = temp.next;
    }

    //循环退出,即找不到相同的key
    System.out.println("该数据不存在!");
    return null;
    }

    /**
    * 打印链表
    */
    public void print() {
    if (headNode == null) {
    return;
    }

    Node temp = headNode;
    while (temp != null) {
    System.out.print(temp + " ");
    temp = temp.next;
    }
    }
    }

    //---------------------------------------------------------------------
    private int size; //数组长度
    private LinkedList[] linkedList; //链表数组

    public HashTable() {
    this(5); //默认数组长度为5
    }

    public HashTable(int size) {
    this.size = size;
    linkedList = new LinkedList[size];
    }

    /**
    * 添加数据
    * @param key 关键词
    * @param data 数据
    */
    public void add(String key, Object data) {
    //通过散列函数分配数组index
    int index = hashFun(key);

    //链表为空,就先创建一个链表
    if (linkedList[index] == null) {
    linkedList[index] = new LinkedList();
    }

    linkedList[index].add(key, data);
    }

    /**
    * 通过关键词获取数据
    * @param key 关键词
    * @return Object
    */
    public Object get(String key) {
    //通过散列函数分配数组index
    int index = hashFun(key);

    //链表为空,一定不存在数据
    if (linkedList[index] == null) {
    System.out.println("数据不存在!");
    return null;
    }

    return linkedList[index].get(key);
    }

    /**
    * 打印数据
    */
    public void print() {
    //遍历数组打印链表
    for (LinkedList list : linkedList) {
    if (list != null) {
    list.print();
    }
    }
    System.out.println();
    }

    /**
    * 散列函数
    * @param key 关键词
    * @return int
    */
    private int hashFun(String key) {
    //每个类会有一个与之对应的hashCode
    int code = key.hashCode();

    //取模,是最简单的散列函数
    return code % size;
    }
    }
  • (2)测试
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Test
    public void hashTableTest() {
    //创建哈希表,并添加数据
    HashTable hashTable = new HashTable();
    hashTable.add("id", 1);
    hashTable.add("name", "C酱");
    hashTable.add("age", 18);
    hashTable.add("sex", "女");
    hashTable.print();

    //通过关键词获取数据
    Object sex = hashTable.get("sex");
    System.out.println(sex);
    }