堆排序

与堆相关的数据结构

最大堆的特点

堆排序使用的是二叉堆中的最大堆,即:根节点大于所有的子节点,而左右子节点之间没有大小关系。

二叉堆的构造:用一个一维数组存放即可,第i个节点的左右两个子节点分别在2*i, 2*i+1的位置。

堆排序的思路

二叉堆排序的思路:自底向上调整堆,使其满足最大堆的性质,此时根节点就是最大的元素。将根节点与最有一个节点交换之后,将1——n-1个元素看做一个新的堆,再重新调整堆,找到第二大的元素,与新堆最后元素交换,重复上述过程。

python实现:

import random


def adjust_heap(lst, n):
    '''
    调整堆为最大堆
    :param lst: 存放堆的列表
    :param n: 堆的长度
    :return:
    '''
    node_position = int(n/2) #根据堆的性质,算出最后一个非叶子节点的位置
    while node_position >= 1:
        node = node_position -1
        left_node = node_position*2 -1
        right_node = node_position*2 + 1 -1

        #分别判断左右节点是否存在,存在则判断是否需要调整
        if left_node < n:
            if lst[left_node] > lst[node]:
                lst[left_node], lst[node] = lst[node], lst[left_node]
        if right_node < n:
            if lst[right_node] > lst[node]:
                lst[right_node], lst[node] = lst[node], lst[right_node]

        node_position -= 1


def heap_sort(lst):
    for i in range(len(lst))[-1::-1]:
        if i == 0:
            return lst
        else:
            adjust_heap(lst, i+1)           #调整为最大堆
            lst[0], lst[i] = lst[i], lst[0] #将最大元素放置末尾


def main():
    unsorted = [random.randint(0, 99) for _ in range(20)]
    print(unsorted)
    print(heap_sort(unsorted))


if __name__ == '__main__':
    main()

输出:

[94, 2, 5, 57, 76, 61, 16, 45, 84, 67, 28, 56, 2, 3, 96, 58, 17, 28, 13, 26]
[2, 2, 3, 5, 13, 16, 17, 26, 28, 28, 45, 56, 57, 58, 61, 67, 76, 84, 94, 96]

堆排序是稳定的,即不会交换相等元素的位置

堆排序的空间复杂度是O(1),即没有使用额外的空间

堆排序的时间复杂度是O(n*log(n))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值