堆排序
维护的二叉树是一颗完全二叉树,大顶堆用来升序排序,要求父节点大于等于左右子节点。而小丁堆用来降序排序,要求父节点小于等于左右子节点。
/* 堆排序
* 如果按升序排序,就维护最大堆,降序就维护最小堆
* 这里我们按升序讲
* 每次把最大元素放在堆顶,然后交换数组的头尾两个元素,这样数组的最后一个
* 元素就是最大的,然后依次找出剩下的元素中的最大元素,交换,这样就会得到
* 一个升序的数组
* 所以堆排序的时间复杂度为n*logn
*
*/
public class Main {
/*
* 交换头和尾两个数组元素
*
*/
static void swap(int a[], int i, int m){
int t = a[i];
a[i] = a[m];
a[m] = t;
}
/* 这里是将最大的元素找出来,放在堆顶
* 这里logn次
*/
static void fun(int a[], int s, int m){
int temp = a[s];
for(int j=2*s; j<=m; j*=2){
//父节点的两个子节点(可能只有一个子节点)
if(j<m && a[j] < a[j+1]){
j++;
}
//父节点和两个子节点中较大的比较
if(temp>=a[j]){
break;
}
// 将较大的子节点值赋给父节点
a[s] = a[j];
s = j; //为下一次找下一棵子树的较大结点做准备
}
//最后赋值回temp该去的结点位置
a[s] = temp;
}
/* 找n次
*
*/
static void sort(