堆排序(Java实现)

封装成类:

package com.roc.algorithms.sort;

/**
 * 堆排序
 * a[0]不用,实际元素从角标1开始
 * 父节点元素大于子节点元素
 * 左子节点角标为2*k
 * 右子节点角标为2*k+1
 * 父节点角标为k/2
 *
 * @author imroc
 */
public class HeapSort {

    public static void sort(int[] a) {

        //s[0]不用,实际元素数量和最后一个元素的角标都为N
        int N = a.length - 1;

        //构造堆
        //如果给两个已构造好的堆添加一个共同父节点,
        //将新添加的节点作一次下沉将构造一个新堆,
        //由于叶子节点都可看作一个构造好的堆,所以
        //可以从最后一个非叶子节点开始下沉,直至
        //根节点,最后一个非叶子节点是最后一个叶子
        //节点的父节点,角标为N/2
        for (int k = N / 2; k >= 1; k--) {
            sink(a, k, N);
        }
        //下沉排序
        while (N > 1) {
            swap(a, 1, N--); //将大的放在数组后面,升序排序
            sink(a, 1, N);
        }
    }

    //下沉(由上至下的堆有序化)
    private static void sink(int[] a, int k, int N) {
        while (true) {
            int i = 2 * k;
            if (i > N) { //保证该节点是非叶子节点
                break;
            }
            if (i < N && a[i + 1] > a[i]) { //选择较大的子节点
                i++;
            }
            if (a[k] >= a[i]) { //没下沉到底就构造好堆了
                break;
            }
            swap(a, k, i);
            k = i;
        }
    }

    private static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}

测试:

int[] a = {-1, 9, 0, 6, 5, 8, 2, 1, 7, 4, 3};
System.out.println(Arrays.toString(a));
HeapSort.sort(a);
System.out.println(Arrays.toString(a));

输出:
[-1, 9, 0, 6, 5, 8, 2, 1, 7, 4, 3]
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 就如你所说>青春或许就是这样,它比生命更易碎!我们随时都应该小心轻放,那个朋友的青春或许就是因为某一次不小心就这么...
    兔子不爱吃胡萝卜阅读 11,319评论 0 6
  • 这个时候考试应该结束了,我的孩子们,经历了人生中最重大的一次考验,感觉如何?这个时候,我不希望你们悲伤,沮丧,或者...
    两条鱼0001阅读 1,306评论 0 0
  • 每次遇到有肉友和我说多肉植物不好养的时候,我总是会对她说:多肉植物是最好养的植物了。为什么呢? 很多人经常说养不好...
    六六多肉花园阅读 2,885评论 0 0
  • 不要轻易去试探人心,有时候,试着试着,心就散了。
    大大大榴莲阅读 1,241评论 0 0
  • 山跟着水流走 一座一座 在静静的夜里 不可捉摸 月亮在跟着家乡 在节日里 我想 她就是酒 她就是愁 所以 大家醉的...
    不吃道阅读 1,501评论 2 3