数据结构—堆

一.堆的概念:
堆逻辑上是一颗完全二叉树,采用层次遍历的方式,物理上存储在数组中。
满足任意结点的值都大于其子树中结点的值,叫大堆,反之叫小堆。
二.下标关系:
1.已知双亲的下标,则:
left=2parent+1;
right=2
parent+2;

2.已知孩子下标,则:
parent=(child-1)/2 //向下取整

三.向下调整
前提:左右子树必须已经是一个堆,才能调整。
过程(以小堆为例):
1.如果index是叶子结点,则调整过程结束。
判断左孩子下标是否越界
2.判断left或right谁是最小孩子min。
如果右孩子下标越界min=left
如果都不越界,判断array[left]和array[right]谁的值小。
3.比较array[index]和array[min]的值,如果array[index]大,则交换。
4.index=min,min作为新的index循环下去。
时间复杂度为:O(log2 n)

(小堆)

public static void shiftDown(int[]array,int index,int size){
int left=2*index+1;
while(left<size){
int min=left;
int right=left+1;
if(right<size){
if(array[left]>array[right]){
min=right;
}
}
if(array[index]>array[min]){
int t=array[index];
array[index]=array[min];
array[min]=array[index];
index=min;
}
left=2*index+1;
}
}

四.建堆
找到最后一个有孩子结点的结点,进行向下调整。
时间复杂度为:O(nlog2 n)

public static void creatHeap(int[] array,int size){
for(int i=(size-2)/2;i>=0;i--){
shiftDown(array,size,i);
}
}

堆—动态查找
1.出队列
2.入队列
3.队首元素(当前优先级最高的元素)

利用堆可以找最值的基本功能,完成其他应用
1.TopK
在海量数据中,寻找前k大的数据
找排名前k大的,建k个大小的小堆

堆排序是选择排序

public class HeapSort{
public static void heapSort(int[] array){
creatBigHeap(array);    //建大堆
//选出array.length-1个数
for(int i=0;i<array.length-1;i++){
//无序:[0,array.length-i)
//有序:[0,array-i-1]
swap(array,0,array.length-i-1);
//无序的长度-1
//array.length-i-1
shiftDown(array,array.length-i-1,0);
}
}
private static void createBigHeap(int[] array){
for(int i=(array.length-2)/2;i>=0;i--){
shiftDown(array,array.length,i);
}
}
private static void shiftDown(int[] array,int size,int i){
while(2*i+1<size){
int max=2*i+1;
if(max+1<size){
if(array[max+1]>array[max]){
max=max+1;
}
}
if(array[i]>=array[max];
return;
}
swap(array,i,max);
i=max;
}
}
private static void swap(int[] array,int i,int j){
int t=array[i];
array[i]=array[j];
array[j]=t;
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值