堆排序java实现

网上很多堆排序都有问题,我写的这个我测试是没问题的,如果有问题请指出!

算法思想

堆排序是利用堆这个数据结构,堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆这个等我写完排序再看。

算法步骤

1.将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
2.将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

代码实现

class HeapSort{
    public static void main(String[] args) {
       int []a= {1,3,2,4,5,4,8,6,-1,10};
       int n=a.length;
       //建堆,下标一定要n/2-1开始,算法导论数组是从1开始的,网上很多有问题。
       for (int i=n/2-1;i>=0;i--){
           maxHeap(a,n,i);
       }
       //交换最大值到最后的位置
       for (int j=n-1;j>0;j--){//j到1的时候就只需要交换0,1,不会再调整堆了
           int t=a[0];
           a[0]=a[j];
           a[j]=t;
           maxHeap(a,j,0);//其他地方已经满足大顶堆性质,只需要从根元素再调整一次,长度变成j
       }
       for (int i=0;i<n;i++) {
           System.out.print(a[i]+",");
       }
    }
    public static void maxHeap(int[]a,int n,int index){
        for (int k=2*index+1;k<n;k=2*index+1){
            int temp=a[index];
            //找到最大的子节点
            if (k+1<n&&a[k+1]>a[k])k++;
            //如果子节点大则交换父子节点
            if (a[k]>temp){
                a[index]=a[k];
                a[k]=temp;
                //这里是重点,如果交换,则要看会不会对子树有什么影响,上面for循环体内结束是k=2*index+1,
                // 如果没到子节点,得继续检查子树
                index=k;
            }
            else break;//如果没换则直接终止
        }
    }
}

算法分析

外层循环规模为n,manHeap里面的循环规模取2为底n的对数,总的复杂度是O(nlog(n)),补充一点,推排序一般用不到,但是构建堆的过程经常用来进行部分排序,降低总体时间复杂度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值