Java集合——hash表

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

数组的特点是:寻址容易,插入和删除困难;

而链表的特点是:寻址困难,插入和删除容易。

综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构,这就是哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法——拉链法,我们可以理解为“链表的数组”,如图:
这里写图片描述
左边很明显是个数组,数组的每个成员包括一个指针,指向一个链表的头,当然这个链表可能为空,也可能元素很多。我们根据元素的一些特征把元素分配到不同的链表中去,也是根据这些特征,找到正确的链表,再从链表中找出这个元素。

哈希构造:
1.直接寻址法 : f(key) = key 或者 f(key) = a ´ key + b 此法仅适合于:地址集合的大小 = = 关键字集合的大小,其中a和b为常数。
2.除留余数法: 设定哈希函数为:H(key) = key%n ( n≤m ),其中, m为表长(容量),n 为不大于 m 的素数,或是不含 20 以下的质因子

哈希冲突解决:
1.链地址法:(数组+单向链表)
2.探测法:pos(n)=f(n)+p(n)

线性探测 :p(n)=1
p(n)=2,,,,,,

随机探测:p(n)=random()

代码:

/**
 * 
 */
package com.tulun.jihe;

/**
 * @author lzq
 *
 */
public class HashMap {
    /**
     * 节点类
     * @author 李正全
     *
     */
    class Entry{
        /**
         * 键
         */
        int key;
        /**
         * 值
         */
        String val;
        /**
         * 下一个节点
         */
        Entry next;
        /**
         * 构造方法
         * @param key   键
         * @param val   值
         */
        public Entry(int key, String val) {
            this.key = key;
            this.val = val;
        }



    }
    /**
     * 当前的Hash表长度
     */
    int size;
    /**
     * 数组
     */
    Entry[] array;

    /**
     * 构造函数,初始化
     */
    public HashMap() {
        this.size = 0;
        array = new Entry[10];
    }   

    /**
     * put方法
     * @param key 键
     * @param val 值
     */
    public void put(int key,String val) {   
        //临时Key
        int tempKey = key%10;
        Entry node = new Entry(key, val);
        if(array[tempKey] == null) {
            array[tempKey] = node;
         } else {
             insertTail( array[tempKey], node);
         }
         size++;
    }
    /**
     * 尾插法
     * @param head      头结点
     * @param newNode   新节点
     */
    private void insertTail(Entry head,Entry newNode){
        if(head==null){
            return;
        }
        Entry temp = head;
        while(temp.next!=null){
            temp = temp.next;
        }
        temp.next = newNode;
    }
    /**
     * get方法
     * @param key 键
     * @return
     */
    public String get(int key){
        int tempKey = key%10;
        Entry tempNode = array[tempKey];
        while(tempNode!=null){
            if(tempNode.key == key){
                return tempNode.val;
            }
            tempNode = tempNode.next;
        }
        return null;
    }

    public void remove(int key){
        int tempKey = key%10;
        Entry tempNode = array[tempKey];
        Entry tempNode2 = array[tempKey].next;
        if(tempNode2== null){
            array[tempKey] = null;
        } else {
        while(tempNode2 != null){
            if(tempNode2.key == key){
                break;
            }
            tempNode = tempNode.next;
            tempNode2 = tempNode2.next;
        }
        tempNode.next = tempNode.next.next;
        tempNode2 = null;
        }
        size--;
    }

    public void test(){
        HashMap a = new HashMap();
        a.put(50, "图论");
        a.put(20, "中国");
        a.put(52, "李正全");
        a.put(64, "算法");
        a.put(96, "数据");
        a.put(57, "计算机");
        a.put(47, "电脑");
        a.put(79, "笔记本");
        a.put(9, "Java");
        a.put(19, "前端");
        System.out.print(a.get(50)+" ");
        System.out.print(a.get(20)+" ");
        System.out.print(a.get(52)+" ");
        System.out.print(a.get(64)+" ");
        System.out.print(a.get(96)+" ");
        System.out.print(a.get(57)+" ");
        System.out.print(a.get(47)+" ");
        System.out.print(a.get(79)+" ");
        System.out.print(a.get(9)+" ");
        System.out.println(a.get(19));
        a.remove(64);
        System.out.println("================");
        System.out.println("删除后:");
        System.out.println("================");
        System.out.print(a.get(50)+" ");
        System.out.print(a.get(20)+" ");
        System.out.print(a.get(52)+" ");
        System.out.print(a.get(64)+" ");
        System.out.print(a.get(96)+" ");
        System.out.print(a.get(57)+" ");
        System.out.print(a.get(47)+" ");
        System.out.print(a.get(79)+" ");
        System.out.print(a.get(9)+" ");
        System.out.println(a.get(19));
    }

}

运行结果:

图论 中国 李正全 算法 数据 计算机 电脑 笔记本 Java 前端
================
删除后:
================
图论 中国 李正全 null 数据 计算机 电脑 笔记本 Java 前端

猜你喜欢

转载自blog.csdn.net/qq2899349953/article/details/80787808
今日推荐