必学经典算法之——堆排序

堆的定义

n个元素的序列{k1,k2,k3, ... ,kn},当且仅当满足以下关系时,称之为堆。



堆排序要点

建堆:将n个元素建成堆。

排序:输出堆顶元素后,调整剩余元素,使之成为大根堆;继续输>出堆顶,继续调整,依此类推。

(一)筛选:调整堆使之成为大根堆或小根堆
输出堆顶元素后,将堆底元素送入堆顶,由于根结点不满足堆的性质,此时堆被破坏,而根结点的左右子树仍然是堆。然后,将根结点与左右子树,较大或者较小的进行比较。如果与左子树交换,左子树破坏;如果与右子树交换,右子树破坏。继续对不满足堆性质>的子树就行上述操作,直到叶子结点。

排序的过程就是不断输出堆顶并进行筛选的过程。

(二)建堆:建堆的过程就是从底向上对每一个非叶子结点进行一次筛选即可。

时间和空间复杂度

每输出一次堆顶元素需要进行一次调整,每次调整需要的比较次数>为logn,时间复杂度O(logn),n次输出总共需要的比较次数为O(nlogn)。

空间复杂度为O(n)。


代码实现

public class HeapSort {
    // 已知除了arr[low],其他元素满足堆的定义
    public static void heapAdjust(int[] arr, int low, int high) {
        int temp = arr[low];
        for (int i = low * 2 + 1; i < high; i = i * 2 + 1) {
            if ((i + 1) < high && arr[i] < arr[i + 1]) {
                i++;
            }
            if (temp < arr[i]) {
                arr[low] = arr[i];
                low = i;
            } else {
                break;
            }
        }
        arr[low] = temp;
        System.out.println("adjust:"+JSON.toJSONString(arr));
    }

    public static void heapSort(int[] arr) {
        int n = arr.length;
        //初始化堆,从下向上建堆
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapAdjust(arr, i, n);
        }
        System.out.println("done");
        //排序,输出头节点,把最后叶子结点的值赋值给头节点,调整
        for (int i = n - 1; i > 0; i--) {
            int head = arr[0];
            arr[0] = arr[i];
            arr[i] = head;
            heapAdjust(arr, 0, i);
        }
    }

    public static void main(String[] args) {
        int[] arr = {0,1,2,3,4,5,6,7,8,9,10};
        heapSort(arr);
        System.out.println(JSON.toJSONString(arr));
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值