java算法之堆排序

来源:互联网 发布:linux 支持无线网卡 编辑:程序博客网 时间:2024/06/06 03:07


堆实质上是满足如下性质的完全二叉树:树中任一非叶节点的关键字均不大于(或者不小于)其左右孩子(若存在)节点的关键字。
每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。
每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。

基本思想

  1. 把数据初始化成堆(大根堆)
  2. 每次交换第一个和最后一个元素,得到最后一个元素(最大值),然后把剩下元素重新调整为大根堆。

    代码

public class HeapSort {    public static void init(int[] arr, int parent, int length) {        int temp = arr[parent]; // temp保存当前父节点        int child = 2 * parent + 1; // 先获得左孩子        while (child < length) {            // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点            if (child + 1 < length && arr[child] < arr[child + 1]) {                child++;            }            // 如果父结点的值已经大于孩子结点的值,则直接结束            if (temp >= arr[child])                break;            // 把孩子结点的值赋给父结点            arr[parent] = arr[child];            // 选取孩子结点的左孩子结点,继续向下筛选            parent = child;            child = 2 * child + 1;        }        arr[parent] = temp;    }    public static void heapSort(int[] arr) {        // 循环建立初始堆        for (int i = arr.length / 2; i >= 0; i--) {            init(arr, i, arr.length - 1);        }        // 进行n-1次循环,完成排序        for (int i = arr.length - 1; i > 0; i--) {            // 最后一个元素和第一元素进行交换            int temp = arr[i];            arr[i] = arr[0];            arr[0] = temp;            // 筛选 R[0] 结点,得到i-1个结点的堆            init(arr, 0, i);        }    }    public static void main(String[] args) {        int[] a = new int[] { 49, 38, 65, 97, 76, 13, 27, 50 };        heapSort(a);        for (int i : a)            System.out.print(i + " ");    }}

时间复杂度
O(nlog2n)

原创粉丝点击