目录
1. 优先级队列的概念
1.1堆的概念
1.2堆的性质
1.3堆的存储方式
2. 堆的创建
2.1堆的创建代码解析
2.2建堆的时间复杂度
2.3堆的插入
2.4 堆的删除
2.5常见习题
队列是一种先进先出 (FIFO) 的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队 列时,可能需要优先级高的元素先出队列, 在这种情况下, 数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象 。这种数 据结构就是 优先级队列 (Priority Queue) 。
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
以大根堆为例:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。
从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储
如果 i 为 0 ,则 i 表示的节点为根节点,否则 i 节点的双亲节点为 (i - 1)/2如果 2 * i + 1 小于节点个数,则节点 i 的左孩子下标为 2 * i + 1 ,否则没有左孩子如果 2 * i + 2 小于节点个数,则节点 i 的右孩子下标为 2 * i + 2 ,否则没有右孩子
public class TextHeap {
public int[] arr;
public int size;
public TextHeap(int[] arr) {
this.arr = arr;
size=arr.length;
}
public void createheap(){
for (int parent = (size-1-1)/2; parent >=0 ; parent--) {
shiftDown(parent,size);
}
}
private void shiftDown(int parent,int len){
int child=2*parent+1;
while(childarr[child]){
child++;
}
if(arr[parent]
向下过程(以大根堆为例):
- 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子)
- 如果parent的左孩子存在,即:child < size, 进行以下操作,直到parent的左孩子不存在
parent右孩子是否存在,存在找到左右孩子中最大的孩子,让child进行标将parent与较大的孩子child比较。
如果parent大于较大的孩子child,调整结束。
否则:交换parent与较大的孩子child,交换完成之后,parent中大的元素向下移动,可能导致子树不满足对的性质,因此需要继续向下调整即parent = child;child = parent*2+1; 然后继续(2)。
public void shiftUp(int child){
int parent=(child-1)/2;
while(child>0){
if(arr[child]>arr[parent]){
int tmp = arr[parent];
arr[parent] = arr[child];
arr[child] = tmp;
child=parent;
parent=(child-1)/2;
}else {
break;
}
}
}
public void offer(int val) {
if (isfull()) {
arr = Arrays.copyOf(arr, arr.length * 2);
}
arr[size++] = val;
}
public boolean isfull() {
return arr.length == size;
}
从0开始插入建堆的时间复杂度
public boolean empty() {
return 0 == size;
}
public void pop(){
if (empty()){
return;
}
int tmp = arr[0];
arr[0] = arr[size-1];
arr[size-1] = tmp;
size--;
shiftDown(0,size);
}
3.最小堆[0,3,2,5,7,4,6,8],在删除堆顶元素0之后,其结果是()
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞