update list&tree

This commit is contained in:
ranwenjie
2021-12-22 17:12:08 +08:00
parent 3cc2b2da12
commit 667624355c
10 changed files with 212 additions and 51 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

+89 -9
View File
@@ -6,18 +6,18 @@
特点
* 堆总是一颗完全二叉树树, 使用数组作为其存储结构,因此也叫 `二叉堆`; 用链表存的就叫二叉树了
* 任一节点小于(或大于)其所有的孩子节点;
* 任一节点小于(或大于)其所有的孩子节点;
* 堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。
* 小根堆: 每次取出来的元素都是队列中值最小的
堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。
`堆用数组来存储`,因为是一颗完全二叉树,i节点的父节点索引就是(i-1)/2, 左右子节点小标是 2i+1,2i+2。
比如大根堆存储示例
```
10, 7, 6 , 3, 4, 1, 5
```
比如小根堆存储示例
![小根堆](./pq-1.png)
### 应用场景
@@ -28,6 +28,88 @@
### Java PriorityQueue
Java PriorityQueue 类就是 通过二叉小顶堆实现 ,也叫优先级队列实现。 有如下特点:
* 实现 Queue 接口
* 头部是基于自然排序或基于比较器的排序的最小元素
* 不是线程安全的,PriorityBlockingQueue在并发环境中使用
API 如下:
* boolean add(object):将指定的元素插入此优先级队列。
* boolean offer(object):将指定的元素插入此优先级队列。
* boolean remove(object):从此队列中删除指定元素的单个实例(如果存在)。
* Object poll():检索并删除此队列的*头部*,如果此队列为空,则返回null。
* Object element():检索但不删除此队列的*头部*,如果此队列为空,则返回null。
* Object peek():检索但不删除此队列的*头部*,如果此队列为空,则返回null。
* void clear():从此优先级队列中删除所有元素。
```
{
PriorityQueue<Employee> pq = new PriorityQueue();
pq.add(new Employee(1L, "AAA", LocalDate.now()));
pq.add(new Employee(4L, "BBB", LocalDate.now()));
pq.add(new Employee(3L, "DDD", LocalDate.now()));
pq.add(new Employee(7L, "GGG", LocalDate.now()));
pq.add(new Employee(2L, "CCC", LocalDate.now()));
while (true) {
Employee head = pq.poll();
System.out.println(head);
if (head == null) {
return;
}
}
}
```
输出
```
Employee [id=1, name=AAA, dob=2021-12-22]
Employee [id=2, name=CCC, dob=2021-12-22]
Employee [id=3, name=DDD, dob=2021-12-22]
Employee [id=4, name=BBB, dob=2021-12-22]
Employee [id=7, name=GGG, dob=2021-12-22]
```
如下,使用 PriorityQueue实现的 top-K 大问题,实现如下:
```Java
/**
* 小根堆实现
*/
public static int findMaxK(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>(k, (a, b) -> (a-b) );
for (int i = 0; i <nums.length ; i++) {
//取出前k个元素放入 PQ 中
if (i < k) {
pq.add(nums[i]);
continue;
}
Integer head = pq.peek();
if (head < nums[i]) {//维护 priorityQueue 中元素只有k个
pq.poll();
pq.add(nums[i]);
}
}
return pq.poll();
}
```
# 堆存储结构
@@ -47,8 +129,6 @@
优先级队列的代码实现