LittleSkinny

哈希表

1、概念

  • 存储键值对的数据结构

  • 实现

    • 数组 + 链表

    • 数组 + 二叉树

2、应用场景

  • 字典:

    • 键:单词

    • 值:释义(找出单词的释义)

  • 图书索引:

    • 键:术语

    • 值:一串页码(找出相关的页码)

  • 文件共享:

    • 键:歌曲名

    • 值:计算机ID(找到歌曲的下载地址)

  • 账户管理:

    • 键:账户号码

    • 值:交易详情(处理交易)

  • 网络搜索:

    • 键:关键字

    • 值:网页名称(找出相关网页)

  • 编译器:

    • 键:变量名

    • 值:类型和值(找出符号的类型和值)

3、自定义哈希表

  • 数组 + 链表

    public class MyHashMap {
    ​
        // 存储链表的数组
        private int size = 8;
        private LinkedList[] array = new LinkedList[size];
    ​
        // 构造函数
        public MyHashMap(){
            for (int i = 0; i <size ; i++) {
                array[i] = new LinkedList();
            }
        }
    ​
        // 结点
        private static class Node{
            int key;
            int value;
            Node next;
    ​
            public Node(int key) {
                this.key = key;
            }
    ​
            public Node(int key, int value) {
                this.key = key;
                this.value = value;
            }
    ​
            public Node(int key, int value, Node next) {
                this.key = key;
                this.value = value;
                this.next = next;
            }
        }
    ​
        // 链表
        public static class LinkedList{
    ​
            // 头结点
            private Node head = null;
    ​
            // 添加结点
            public void add(Node newNode){
                // 如果head为空,说明此时该链表上没有元素,把新结点添加到头结点后
                if (head == null){
                    head = newNode;
                }
                // 否则,把新结点添加到链表的最后一个元素上
                else {
                    // 遍历链表,找到最后一个元素
                    Node temp = head;
                    while (temp.next != null){
                        temp = temp.next;
                    }
    ​
                    // 把新结点添加到最后一个结点上
                    temp.next = newNode;
                }
            }
    ​
            // 遍历链表
            public void list(){
    ​
                if (head == null){
                    System.out.println("空");
                }
    ​
                Node temp = head;
                int index = 1;
                while (temp != null){
                    System.out.print("第" + index + "个结点:键为:" + temp.key + " 值为:" + temp.value);
                    System.out.print(";");
                    temp = temp.next;
                    index ++;
                }
                System.out.println();
            }
    ​
            // 删除结点
            public void delete(Node node){
    ​
                if (head == null){
                    return;
                }
    ​
                // 如果头结点为要删除的结点
                if (head == node){
                    head = node.next;
                    return;
                }
    ​
                // 找到node结点的前一个结点
                Node temp = head;
                while (temp.next != node){
                    temp = temp.next;
                }
                // 删除node结点
                temp.next = node.next;
                node.next = null;
            }
        }
    ​
        // 哈希表存值
        public void put(int key, int value) {
    ​
            int keyTemp = key % size;
    ​
            if(array[keyTemp].head == null){
                array[keyTemp].add(new Node(key,value));
            }else{
                // 如果遍历链表的时候发现链表中有相同key,覆盖原值
                Node temp = array[keyTemp].head;
                boolean flag = true;
                while (temp != null){
                    if (temp.key == key){
                        temp.value = value;
                        flag = false;
                        break;
                    }
                    temp = temp.next;
                }
                // 遍历结束,没有发现相同key,添加结点
                if (flag){
                    array[keyTemp].add(new Node(key,value));
                }
    ​
            }
    ​
        }
    ​
        // 遍历哈希表
        public void list(){
            for (int i = 0; i <size ; i++) {
                System.out.print("第" + (i + 1) + "条链表:");
                array[i].list();
            }
        }
    ​
        // 哈希表取值
        public int get(int key) {
    ​
            // 根据key值决定,在数组中的哪个链表中查找
            int keyTemp = key % size;
            if (array[keyTemp].head == null){
                return -1;
            }else{
                Node temp = array[keyTemp].head;
    ​
                while (temp.key != key){
                    if (temp.next == null && temp.key != key){
                        return -1;
                    }
                    temp = temp.next;
                }
    ​
                return temp.value;
    ​
            }
        }
    ​
        // 哈希表删除值
        public void remove(int key) {
    ​
            // 根据key确定在数组中的哪一个链表中删除元素
            int keyTemp = key % size;
            // 如果链表中存在该键,删除键值对
            // 遍历链表
            Node temp = array[keyTemp].head;
            if (temp == null){
                return;
            }else {
                while (temp != null){
                    if (temp.key == key){
                        array[keyTemp].delete(temp);
                        break;
                    }
                    temp = temp.next;
                }
            }
        }
    }
    

     

     



相关文章: