排序算法--堆排序之堆的构建以及怎样通过heapify操作完成堆排序
作者:互联网
堆
1.堆简介:
- 堆是一个完全二叉树,这就是它的一个优秀的特点,因此可将它看为一个一维数组,并且每个结点都对应数组元素。
- 堆的根结点>孩子结点(称为大堆)或 根结点<孩子结点(称为小堆)。
(本篇文章全以大堆为例)
2,堆排序
堆排序可以看做以下几个步骤: - ①将一个完全无序的数组建成堆
- ②建成的堆的根结点就是所有结点中最大值,将其与最后一个结点交换
- ③砍断最后一个结点,即得到了这个数组中的最大值
- ④重新从新的第一个结点开始堆化
- 重复以上步骤,直到堆中只剩一个结点
举例:
①这是一个建好的大堆:
②交换根结点和最后一个结点,砍断最后一个结点
因为交换了根结点和最后一个结点,此时一定破坏了堆的结构,所有要对其从根结点开始重新堆化。
③再次交换根结点和最后一个结点,砍断,堆化。这样重复下去直到堆中只有一个结点
注意:
- 堆化的前提是是完全二叉树并且只有一个地方不满足堆的条件,堆化是从上往下
- 建堆程是从第一个非叶子结点到根结点一直做堆化的过程
- 具体的建堆以及堆化大家快去看up主正月点灯笼的视频啦,超级棒!
Java实现:
//堆排序
private static void heapSort(int[] array,int size){
//建堆
createHeap(array);
for(int i=size-1;i>=0;i--){
//交换根结点(最大值)和最后一个结点
int tmp=array[i];
array[i]=array[0];
array[0]=tmp;
//砍断最后一个结点并继续堆化,得到新的根结点(最大值)
heapify(array,0,i);
}
}
private static void createHeap(int[] array){
for(int i=(array.length-2)/2;i>=0;i--){
heapify(array,i,array.length);
}
}
private static void heapify(int[] array, int index,int size) {
int max=index*2+1; //假定左孩子是最大值
while(max<size){ //左孩子存在
if(max+1<size && array[max+1]>array[max]){ //如果右孩子存在并且右孩子是最大值,交换
max=max+1;
}
if(array[index]>=array[max]){ //如果要堆化的结点值本身就大于最大值,直接退出循环
break;
}
//否则交换要堆化的结点值和最大值
int tmp=array[index];
array[index]=array[max];
array[max]=tmp;
index=max; //向下继续堆化
max=max*2+1
}
}
标签:结点,之堆,堆化,int,max,最大值,堆排序,heapify,array 来源: https://blog.csdn.net/gaga_yu/article/details/89577257