一、Hash基础
1.1哈希基础概念
哈希 (Hash)也称为散列,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,这个输出值就是散列值。并且不同的明文很难映射为相同的 Hash 值。
哈希为什么访问的时间复杂度是O(1)呢?
因为哈希以一定规律将数值放在一个列表中,列表中每个结构下面都有很多个值,在搜索某个值时可以直接找到在列表中的位置,然后再内部在搜索。
这里会产生一个疑问?那会不会在查询的时候产生冲突呢?
在上面的例子中,我们发现有些在Hash中很多位置可能要存两个甚至多个元素,很明显单纯的数组是不行的,这种两个不同的输入值,根据同一散列函数计算出的散列值相同的现象叫做碰撞。
1.2碰撞处理方法
1.2.1开放地址法
开放寻址法: 将所有的元素都存放在哈希表的数组中,不使用额外的数据结构,一般使用线性探查的思路解决。将索引重复的值放在空余的位置上。
1.2.2链地址法
链地址法是在哈希索引上生成一个链结构。索引的长度是2的n次幂,当entry的数量大于长度的75%,会触发扩容机制进行扩容。
二、队列
2.1队列基本概率
队列是一个先进先出,后进后出的队列。
2.2基于链表实现队列
import lombok.Data;
public class MyQueue {
//队列头
private Node front;
//队列尾
private Node rear;
private int size;
@Data
public class Node {
private int val;
private Node next;
public Node(int val) {
this.val = val;
}
}
MyQueue() {
front = new Node(0);
rear = new Node(0);
}
/**
* 入队
*
* @param val 入栈的值
*/
public void push(int val) {
Node newNode = new Node(val);
Node temp = front;
while (temp.next != null) {
temp = temp.next;
}
temp.next = newNode;
rear = newNode;
size++;
}
/**
* 出队
* @return 队头元素
*/
public int pull(){
if (front.next == null)
System.out.println("队列为空");
Node res = front.next;
front.next = res.next;
size--;
return res.val;
}
/**
* 遍历队列
*/
public void traverse(){
Node temp = front.next;
while (temp!=null){
System.out.println(temp.val);
temp = temp.next;
}
}
public static void main(String[] args) {
MyQueue myQueue = new MyQueue();
myQueue.push(1);
myQueue.push(2);
myQueue.push(3);
int pull = myQueue.pull();
System.out.println(pull);
System.out.println();
myQueue.traverse();
}
}