堆排序_HeapSort
HEAPSORT:理解的不透彻,还要写
1.堆排序算法基本思想
Grammar Thoughts:
*将待排序
的序列构造成一个大顶堆
整个序列的最大值就是堆顶的根节点,将其去对数组的末尾元素交换,然后将剩余的(n-1)个系列重新构造成一个堆,这样就会得到n个元素中的次最大值,如此反复执行费
,就可以得到一个有序序列
堆:完全二叉树
2.代码实现_(Java)
package SevenSorts;
/**
* Grammar Thoughts:
*将待排序的序列构造成一个大顶堆
* 整个序列的最大值就是堆顶的根节点,将其去对数组的末尾元素交换,然后将剩余的(n-1)个系列重新构造成一个堆,这样就会得到n个元素中的次最大值,如此反复执行费
* ,就可以得到一个有序序列
*
* 堆:完全二叉树
*/
public class HeapSort {
//==========================================================================
//将序列改成大顶堆
public static void heapSort(int[] arr){
if(arr==null||arr.length==1) return;
//数组转换为大顶堆
buildArrToHeap(arr);
}
//构造大顶堆(可以是小顶堆)--看你自己怎么去实现
private static void buildArrToHeap(int[] arr) {
if(arr==null||arr.length==1){
return;
}
//递推公式就是:int root=2*i,int left=2*i+1; int right=2*i+2;
int cursor=arr.length/2;
for(int i=cursor;i>=0;i++){
//构造大顶堆
buildMaxHeap(arr,arr.length,i);
}
}
private static void buildMaxHeap(int[] arr, int heapSize, int index) {
//左右子节点
int left=index*2+1;
int right=index*2+2;
//当前父节点index暂定为最大值(哨兵作用)
int maxVal=index;
//将左右子节点与父节点比较,如果子节点大于父节点交换(左右比较的顺序不能够改变)
if(left<heapSize&&arr[left]>arr[maxVal]){
maxVal=left;
}
if(right<heapSize&&arr[right]>arr[maxVal]){
maxVal=right;
}
//如果不相等说明有子节点比父节点打的,交换位置
if(maxVal!=index){
swap(arr,maxVal,index);
}
//还哦需要进行最后一个判断:看看子节点是否打破了最大堆的性质(子节点是够都比父节点小),
buildMaxHeap(arr,arr.length,index);
}
private static void swap(int[] arr, int i, int j) {
arr[i]^=arr[j];
arr[j]^=arr[i];
arr[i]^=arr[j];
}
//==========================================================================
//大顶堆优化实现算法
//==========================================================================
//初始化数组和构造器
private int[] arr;
public HeapSort(int[] arr){
this.arr=arr;
}
//堆排序的主要入口方法
public void sort(){
/**
* 1.数组堆化
* 2.beginIndex=第一个叶子结点
*从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。
** 叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大
*/
int len=arr.length-1;
int beginIndex=(len-1)>>1;
for(int i=beginIndex;i>=0;i--){
maxHeapify(i,len);
}
for (int j = len; j > 0 ; j--) {
swap_2(0,j);
maxHeapify(0,j-1);
}
}
private void swap_2(int i, int j) {
i=i^j;
j=i^j;
i=i^j;
}
//堆堆化数据排序
private void maxHeapify(int index, int len) {
//左节点的索引
int li=(index<<1)+1;
int ri=li+1;
int cMax=li;
if(li>len) return;
if(ri<=len&&arr[ri]>arr[li]){
cMax=ri;
}
if(arr[cMax]>arr[index]){
swap_2(cMax,index);
}
maxHeapify(cMax,len);
}
//调整索引为index出的数据
}