堆排序

堆是一种重要的数据结构,为一棵完全二叉树, 底层如果用数组存储数据的话,假设某个元素为序号为i(Java数组从0开始,i为0到n-1),如果它有左子树,那么左子树的位置是2i+1,如果有右子树,右子树的位置是2i+2。
堆排序最重要的是构建大顶堆,然后让大顶堆的0号元素(整个堆的最大元素)与最后一个元素交换,然后通过不断调整大顶堆,不断交换,直到数组有序。

堆排序步骤:
1,构建大顶堆。(从最后一个结点往前构建)
2,0号元素与最后一个元素交换。
3,由于交换可能破坏了大顶堆的结构,所有调整大顶堆。(从第一个结点往后调整)
4,0号元素与最后一个元素交换。
重复34过程,直到整个数组有序。

过程图解
array=[16,7,3,20,17,8]
数组对应的堆
这里写图片描述

构建大顶堆
这里写图片描述

进行第一次交换

这里写图片描述

整个堆的长度减1进行调整,因为已经排序好的元素无需再调整
这里写图片描述
再进行交换
这里写图片描述
之后继续进行调整,交换,直到数组有序

代码

/*调整大顶堆
*/
public static void adjust(int []a,int start,int end ){
        int tmp=a[start];//把当前元素储存起来
        for (int j=2*start+1;j<=end;j=2*j+1){//从i结点的左子结点开始,也就是2i+1处开始
            if(a[j]<a[j+1]&&j+1<=end){//如果左子结点小于右子结点,k指向右子结点
                j++;
            }
            if(a[j]>tmp){//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                a[start]=a[j];
                start=j;
            }
            if(a[j]<tmp){//如果子节点小于父节点,跳出循环
                break;
            }


        }
        a[start]=tmp;//把tmp放到进行赋值给父节点的子节点位置

    }
/*排序代码
*/
    public static void dsort(int []a){
        for(int i=(a.length-1-1)/2;i>=0;i--){
            adjust(a, i,a.length-1);
        }//构建第一个大顶堆;

        for(int j=0;j<a.length;j++){
            /*第一次交换后,此时最后一个元素已经成为最大的元素了
            所以下一次调整的时候不需要调整最后一个元素
            也就是每进行一次交换,堆的长度需要减1
            */
            int tmp = a[0];
            a[0] = a[a.length-1-j];
            a[a.length-1-j] = tmp;
            adjust(a, 0,a.length-1-1-j);//之后不断进行调整,交换,直到数组全部有序
        }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值