算法通关村第五关青铜 | 队列和哈希的特征

1. Hash基础

1.1 Hash的概念和基本特征

哈希其实大家应该都知道一点,哈希也称散列,把任意长度的输入,通过散列算法,变成固定长度的输出值,这个输出值就是散列值。

哈希的存读时间复杂度是O(1),假设有1-15这些数,存到长度是7的哈希表中,存储位置的计算公式是,index = number %  7,求余,余数是几就放在那个位置上。

算法通关村第五关青铜 | 队列和哈希的特征_第1张图片

 要看某个数是否在里面。用上面的求余公式,假如13,对7求余是6,直接访问6这个位置,13在这个位置,时间复杂度是O(1)

1.2 哈希碰撞处理方法

在上面可以发现,数字过多的时候,不同的值,通过散列函数计算出散列值相同的情况就叫碰撞,出现一个位置会有多个数字,那么这些数字在这个位置该怎么存储,常见的方法有:开放定址法(Java里的THreadLocal)、链地址法(Java里的ConcurrentHashMap)、再哈希法(布隆过滤器)、建立公共溢出区。重点看前两个。

1.2.1 开放定址法

这里写一种简单的方法, 当发生冲突的时候,会一次向后找空余的位置,比如1,位置有人就i去2位置,2位置有人就去3位置,。。。直到找到位置,会有扩容机制,下面讲

1.2.2 链地址法

将哈希表的每个单元作为链表的头结点,发生冲突的时候,散列表每个位置的链表会增长,算法通关村第五关青铜 | 队列和哈希的特征_第2张图片

 当然,有可能出现链表过长的情况,如下算法通关村第五关青铜 | 队列和哈希的特征_第3张图片

 上面有两种问题,第一数组的长度必须是2的n次幂,第二,元素的个数不能超过0.75X数组长度,大于的时候会触发扩容机制,每次两倍扩充,0.75是扩容因子,扩充每次都是原数组的二倍,16,32,64...

算法通关村第五关青铜 | 队列和哈希的特征_第4张图片

 2. 队列的基础知识

2.1 队列的概念和基本特征

队列就是日常生活中的排队模式,先来的先买东西,后来的依次在后面等待,即先入队者先 出队,后入队者,后出队,FIFO(first in first out)先进先出,两种实现形式,基于数组和链表。

2.2 实现队列

链表实现,在尾部插入元素,在front删除元素,敲完要测试,会有细节问题

public class LinkQueue {
    private Node front;

    private Node rear;

    private int size;

    public LinkQueue(){
        //虚拟结点
        this.front = new Node(0);
        this.rear = new Node(0);
    }

    //入队,在队尾入

    public void push(int value){
        Node newNode = new Node(value);
        Node temp = front;
        while (temp.next != null){
            temp = temp.next;
        }
        temp.next = newNode;
        rear = newNode;
        size++;
    }

    //出队,返回出队元素
    public int pull(){
        if (front.next == null){
            System.out.println("队列已空");
        }
        Node firstNode = front.next;
        front.next = firstNode.next;
        size--;
        return firstNode.data;
    }

    //遍历队列
    public void traverse(){
        Node temp = front.next;
        while (temp != null){
            System.out.print(temp.data + "\t");
            temp = temp.next;
        }
    }

    static class Node{
        public int data;

        public Node next;

        public Node(int data){
            this.data = data;
        }
    }
//测试
    public static void main(String[] args) {
        LinkQueue linkQueue = new LinkQueue();
        linkQueue.push(1);
        linkQueue.push(2);
        linkQueue.push(3);
        System.out.println("第一个出队元素:" + linkQueue.pull());
        System.out.println("队列元素 :");
        linkQueue.traverse();
    }
}

你可能感兴趣的:(算法通关村专栏,哈希算法,算法)