排序算法-堆排序

Heap Sort

时间复杂度O(nlogn)

最好情况O(nlogn)

最坏情况O(nlogn)

空间复杂度O(1)

In-place


要想理解堆排序,首先需要理解堆这种数据结构。

堆(Heap)是一种特殊的完全二叉树,分为大顶堆和小顶堆,大顶堆中除叶子结点外的每个节点的子节点都小于其父节点,大顶堆中除叶子结点外的每个节点的子节点都大于于其父节点。

我们可以从中得到一个规律,假设数组arr长度为length,其编号中最后一个拥有子节点为叶子结点的编号为 length//2-1。以上图为例,数组长度为9, 最后一个拥有子节点为叶子结点的编号为9//2-1 = 4-1 = 3。该节点的左右子节点编号(若存在)为3*2+1 = 7和3*2+2 = 8。

推排序基本思想,类似于选择排序,每次选择一个最大的数放在他应该在的位置上,由于堆拥有树的性质,意味着每个堆的叶子节点不需要参与搜索,所以比选择排序更快。

其基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

 

  

 


Java:

public class HeapSort {
    public HeapSort(int[] arr){
        for (int i = 0; i < arr.length-1; i++) {
            MakeHeap(arr,arr.length-i);
        }
    }

    public static void MakeHeap(int[] arr,int length){
        int root = length/2-1;
        while (root>=0){
            if(root*2+2<=length-1){
                if(arr[root]<arr[root*2+2]){
                    Switch(arr,root,root*2+2);
                }
                if(arr[root]<arr[root*2+1]){
                    Switch(arr,root,root*2+1);
                }
            }
            if(root*2+1<=length-1){
                if(arr[root]<arr[root*2+1]){
                    Switch(arr,root,root*2+1);
                }
            }
            root--;
        }
        Switch(arr,root+1,length-1);
    }
    public static void Switch(int[]arr,int a, int b){
        int tem;
        tem = arr[a];
        arr[a] = arr[b];
        arr[b] = tem;
    }

}

Python:

def HeapSort(num_list):
    for i in range(len(num_list) - 1):
        MakeHeap(num_list, len(num_list) - i)


def MakeHeap(num_list, length):
    root = length // 2 - 1
    while root >= 0:
        if root * 2 + 2 <= length - 1:
            if num_list[root] < num_list[root * 2 + 2]:
                num_list[root], num_list[root * 2 + 2] = num_list[root * 2 + 2], num_list[root]
            if num_list[root] < num_list[root * 2 + 1]:
                num_list[root], num_list[root * 2 + 1] = num_list[root * 2 + 1], num_list[root]
        if root * 2 + 1 <= length - 1:
            if num_list[root] < num_list[root * 2 + 1]:
                num_list[root], num_list[root * 2 + 1] = num_list[root * 2 + 1], num_list[root]
        root -= 1
    num_list[root + 1], num_list[length - 1] = num_list[length - 1], num_list[root + 1]


def main():
    num_list = [10, 9, 56, 19, 28, 37, 34]
    num_list2 = [5, 4, 3, 1, 2]

    HeapSort(num_list)
    print(num_list)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Weber77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值