堆排序

堆排序集合了插入排序和归并排序的优点,即时间复杂度为nlogn,同时也具备空间原址性:任何时候都只需要常数个额外的元素空间存储临时变量。
它所采用的(二叉)堆是一个数组,可以看出一个近似的完整二叉树,除了最底层,其他都是充满的,所以我们很容易计算出一个结点i的父结点(i/2)、左右孩子结点(2i,2i+1)。
首先创建一个函数maxHeapify(),它的作用是维护堆的性质,输入为一个数组a和一个下标i,我们假设根结点为left(i)和right(i)的二叉树都是最大堆,但a[i]可能小于其左右子结点,所以要让a[i]的值逐级下降至合适的位置,从而从新构成一个最大堆。在维护最大堆的过程中,只维护heapsize内的结点。
然后我们通过自底向上的方式创建一个最大堆,开始heapsize等于数组长度length,然后将根结点与数组最后一个结点对调,heapsize-1,维护最大堆,然后重复上述操作即可完成排序。

//交换两个结点
public void exchange(int []a,int i,int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}


//维护最大堆
public void maxHeapley(int []a,int i,int heapSize){
int left = 2*i + 1;
int right = 2*i + 2;
int maxNum = i;
if((left < heapSize)&&(a[left] > a[i])){
maxNum = left;
}
if((right < heapSize)&&(a[right] > a[maxNum])){
maxNum = right;
}
if(maxNum != i){
exchange(a,i,maxNum);
maxHeapley(a, maxNum,heapSize);
}
}


创建最大堆
public void bulidMaxHeap(int []a){
if((a == null)||(a.length<=1)){
return;
}

for(int i = a.length/2-1;i >= 0;i--){
maxHeapley(a, i, a.length);
}
}



//堆排序
public void heapSort(int a[]){
if((a == null)||(a.length<=1)){
return;
}

bulidMaxHeap(a);
int heapSize = a.length;
for(int i = a.length-1;i > 0;i--){
exchange(a, i, 0);
heapSize --;
maxHeapley(a, 0, heapSize);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值