堆
一、什么是堆
用一个一维数组的方式表示一个完全二叉树
-
假设此时节点的位置在i,其找父节点的方法就是:(i-1)/2
-
其找左孩子的方法为:i*2+1
-
其找右孩子的方法为 i*2+2
-
1完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
-
2完全二叉树中如果每棵子树的最小值都在顶部就是小根堆
二、堆结构的heapInsert与heapify操作
2.1heapinsert
heapinsert又称向上调整。其思路很简单:先和父节点进行比较 看是不是满足条件,满足就交换,然后跳转到父节点2.2 代码
public static void heapinsert(int [] arr,int index) {
while(arr[index]>arr[(index-1)/2]) {//当相等 和为零都会停止。因为不是大于
swap(arr,index,(index-1)/2);
index=(index-1)/2;
}
}
要注意的是: while(arr[index]>arr[(index-1)/2])这个代码片段不管是index等于零,还是arr[index]=arr[(index-1)/2]]都会跳出
注意 : -1/2=0;
2.3heapfy
又称向下调整,先找到左孩子节点的位置,判断是否越界,然后找到又孩子的位置,判断是否越界加哪个更大。然后再将更大的赋值给largest,最后和父节点判断,如果两个节点相同,就直接跳出循环。如果不相同就交换两个节点的值。再接着父变子,循环2.4代码
public static void heapfy(int [] arr,int index,int heapsize) {
int left = index*2+1;
while(left<heapsize) {
int largest = left+1<heapsize && arr[left]<arr[left=1] ? left+1 : left;
largest = arr[index]<arr[largest] ? largest:index;
if(largest==index) {
break;
}
swap(arr,index,largest);
index = largest;
left = index * 2 + 1;
}
}
5,堆结构的建立
一个一个的输入:
代码:
// 一个一个输入,向上调整,O(N*logN)
for(int i = 0; i< arr.length; i++) {
heapinsert(arr,i);
}
直接那全部数组:
代码;
//改良的大根堆建立方法,O(N),具体思路为,直接拿整个数组,从最后开始向下调整。
//由于堆的建立可以建立在前一步的基础上,时间复杂度为O(N)
//叶子节点不会再发生向下调整
//时间复杂度的证明可以用高中的错位相减法证明
for( int i = arr.length - 1 ; i>=0;i--) {
heapfy(arr,i,arr.length);
}
总结
一点了累了