堆排序 java代码实现

堆排序(以大顶堆 升序为例为例)

没有图,就是根据自己理解理清最简单得思路

首先是要明确 大顶堆 小顶堆
  • 大顶堆:每个节点都大于或等于左右子节点(升序用它!
  • 小顶堆:每个节点都小于或等于左右子节点(降序用它!
先说过程:
  1. 创先两个方法,一个用来调整二叉树的结构,一个是用来排序
  2. 在调整中,取得是左右节点最大得节点和需要调整节点做判断
  3. 等二叉树满足条件后,就开始排序,将第一个点放到最后,数组长度减一
  4. 然后再将交换后的二叉树进行调整,使得满足结构
  5. 再反复进行3、4步骤,就完成了排序
以上有个问题(即思路)

怎么和子节点做判断

  • 当前节点为2*sit(root节点为0),每个节点的左右节点为2*sit+1或者2*sit+2,所以需要调整得节点为tmp,所以先取左右节点最大得值再和tmp做判断,做交换,将tmp赋值给小的节点,然后再调整结构,当然这个要循环整个树得深度。跳出条件为当前值大于判断的根节点。

注意要记录上一个值 和当前值 s=lOr, lOr = lOr*2+1

直接看代码吧

public class Heap {

    public static void swap(int[] num,int start, int end){
        // 初始位置 
        int s = start;
        //取的左右节点较大的点的位置
        int lOr = 2*s+1;
        //记录临时值 用于后面交换
        int tmp = num[s];
        
        //当点的值大于数组长度跳出,s作为记录上一个值,lOr作为下一个值,当满足条件后就做交换,这次的点就赋值为tmp
        for(;lOr <= end; s=lOr, lOr = lOr*2+1){
            if(lOr < end && num[lOr] < num[lOr+1]){
                lOr++;
            }
            if(tmp >= num[lOr]){
                break;
            }else {
                num[s] = num[lOr];
                num[lOr] = tmp;
            }
        }
    }


    public static void heapSort(int[] num, int len){
        int i, tmp;
        //先调树结构
        for(i = len/2-1; i >= 0; i--){
            swap(num,i,len-1);
        }
        for(i = len - 1; i > 0; i--){
            tmp = num[0];
            num[0] = num[i];
            num[i] = tmp;
            //排序好一个就调整一次树的结构
            swap(num,0,i-1);
        }

    }

    public static void main(String[] args) {
        int a[] = {1,3,8,2,4,6,11,10,7,9,5};
        System.out.printf("排序前:");
        for (int i=0; i<a.length; i++)
            System.out.print(a[i]+" ");
        System.out.printf("\n");
        heapSort(a, a.length);

        System.out.printf("排序后:");
        for (int i=0; i<a.length; i++)
            System.out.print(a[i]+" ");
        System.out.printf("\n");
    }
}

堆排序不是稳定的排序! 完事儿下班!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值