堆排序 707

大顶堆排序 =^=
把数组处理为大顶堆(或小顶堆)格式,即父节点大于(或小于)两个叶子节点,如不符合要求就把叶子节点的值和父节点的值互换,但是要注意,如果这个叶子节点还有爷爷节点,也需要比较一下

左叶子 2*i + 1
右叶子 2*i + 2
如 num [8,9,11,13],i=0时 num[i]父节点8比 左叶子num[2*0+1] 9小 -> num[9,8,11,13]
之后比较父节点与右叶子,9比num[2*0+2]11小,num[11,8,9,13]
游标往后一位,8的左叶子是13,需要更换为num[11,13,9,8]
这时候就发现会有13比11还大的情况

所以我干脆直接重新排起,然后把一整个数组处理完,第一个值肯定是最大的,当然这是大顶堆做法,小顶堆做法父节点叶子节点比较的时候反一反就可以了。

大顶堆排序代码在下面,如有问题欢迎指出 :

import java.util.*; //最好不要直接用*

public class Main{
    public static void main(String [] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        //  9 6 8 10 3 4 7 2 1 测试用例输入
        String[] s = sc.nextLine().split(" ");
        int num[] = new int[s.length];
        for(int i = 0 ; i < s.length; i++){
            int integer = Integer.parseInt(s[i]);
            num[i] = integer;
        }
        int res[] =new int[s.length]; //创建一个res数组存放结果
        int[] heapsort = heapsort(num, res); //调用排序方法
        for(int i = 0 ; i < heapsort.length; i++){
            System.out.print( heapsort[i] + " ");
        }

    }

    private static int[] heapsort(int[] num,int[]res) {
        buildheap(num,res);
        return res;
    }

    private static int[] buildheap(int[]num,int[] res) {
        sort(num);
        if(num.length==1){  // 出口
            res[0] = num[0]; // 还剩一个值没换,执行不到下面的语句了,直接换了返回完事
            return res;
        };
        //  num 原始数组按照大顶堆逻辑处理后,数组第一个节点即为最大的父节点,保存到res[num.length-1] 的位置
        int temp = num[num.length-1];
        num[num.length-1] = num[0];
        num[0] = temp;
        int newnum[] = new int[num.length-1];
        for(int i = 0; i< newnum.length;i++){
            newnum[i] = num[i];
        }
        res[num.length-1] = num[num.length-1];   //  最大的值单独放到res里
        return buildheap(newnum,res);
    }

    public static int[] sort(int num[]){
        int k = 0;
        for(int i = 0 ; i < num.length/2; i++){
            if(2*i+2>=num.length){  //限制溢出,比较笨,不知道是不是只能这么写
                break;
            }
            //  顺序排 使用大顶堆  左孩子 2*i+1 右孩子 2*i+2  左右孩子比父节点小, 如果大于跟就置换
            if(num[i] < num[2*i+1]){
                int temp = num[2*i+1];
                num[2*i+1] = num[i];
                num[i] = temp;
                k++; //如果替换了,就需要重新排序,因为叶子节点比父节点大 也可能比爷爷节点大
            }
            if(num[i] < num[2*i+2]){
                int temp = num[2*i+2];
                num[2*i+2] = num[i];
                num[i] = temp;
                k++;
            }
            if(k!=0){
                sort(num);
            }
        }
        return num;
    }
}

以后每一种算法都要尝试自己写下来,那才是自己的东西,完结,撒花~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值