08堆排序
基本思想:将数组构成大顶堆,将最大元素其转移至数组(堆)的末尾,再将剩余的n-1个元素构建大顶堆,重复如上操作。
讲解:
//创建一个名为Heap_sort的方法,传入待排数组及其大小
public static void Heap_sort(int a[],int len){
//i从最后一个非叶子节点(叶子结点的下标就是总大小len / 2 - 1)开始,依次向前遍历直到0
for(int i = len / 2 - 1;i >= 0;i--){
//构建大顶堆,传入待排数组a、当前节点i的下标、末尾元素的下标len - 1
HeapAdjust(a,i,len - 1);
}
//第一个循环结束后,此时数组中的第一个元素为数组中的最大值
//从最后一个元素开始向前遍历
for(int i = len - 1;i > 0;i--){
//依次交换相邻元素,目的是将最大元素转移至数组末尾
swap(a,0,i);
//每交换一次,进行一次构建堆,传入数组a,起始位置0,结束位置i - 1
HeapAdjust(a,0,i - 1);
}
}
//创建一个名为HeapAdjust的方法构建大顶堆,传入待排数组a,起始位置start,结束位置end
public static void HeapAdjust(int a[],int start,int end){
//定义变量dad为start,即父节点
int dad = start;
//定义变量son为当前父节点的左孩子节点
int son = dad * 2 + 1;
//循环条件:子节点下标始终不超过边界值
while(son <= end){
//判断子节点大小,选取较大值的那个孩子
if(son + 1 <= end && a[son] < a[son + 1]){
//左孩子下标+1 = 右孩子下标
son++;
}
//若父节点的值大于子节点的值,说明当前的大顶堆构建完成,直接退出
if(a[dad] > a[son]){
return;
//如果不是,则说明仍需要调整
}else{
//首先交换父节点和子节点的值
swap(a,dad,son);
//其次让父节点赋值为子节点的下标
dad = son;
//子节点下标更新为当前父节点下标 * 2 + 1
son = dad * 2 + 1;
}
}
}
//创建一个名为swap的方法,用于交换数组中的元素,传入数组a、待交换元素下标n1、n2
public static void swap(int a[],int n1,int n2){
int temp = a[n1];
a[n1] = a[n2];
a[n2] = temp;
}