蓝桥杯python组知识点之堆排序

堆排序

(1)基本概念

堆排序(Heap Sort)是基于二叉堆的一种排序算法。二叉堆分为两种:最大堆和最小堆。在最大堆中,父节点的值总是大于或等于其子节点的值;而在最小堆中,父节点的值总是小于或等于其子节点的值。

堆排序的核心思想是将一个无序数组构建成一个大顶堆(或小顶堆),然后将堆顶元素(最大值或最小值)与堆尾元素互换,之后将剩余元素重新调整为大顶堆(或小顶堆),以此类推,直到整个数组有序。

堆排序的核心是堆的调整操作,即将一个无序数组构建成一个大顶堆(或小顶堆)。这个过程可以通过自上而下、自下而上的方式进行。自上而下方式是从上到下遍历数组,依次将每个元素插入到合适的位置,使得整个数组满足大顶堆(或小顶堆)的性质。自下而上方式是从下到上遍历数组,每次将当前未调整的元素中最大的(或最小的)元素调整到合适的位置,直到整个数组有序。

参考链接http://t.csdnimg.cn/NrpJm

(2)代码示例

"""堆排序"""
#函数目的:找到当前子数组中的最大值,确保给定的子树满足堆的性质(父节点>=子节点)
def heapify(arr, n, i):#n表示数组的长度,i是当前子树的根节点的索引
    largest = i  
    #计算左右子节点的索引
    left = 2 * i + 1  
    right = 2 * i + 2  
 
    if left < n and arr[left] > arr[largest]:
        largest = left
 
    if right < n and arr[right] > arr[largest]:
        largest = right
 
    if largest != i:#如果largest不是i,则交换arr[i]和arr[largest]
        arr[i], arr[largest] = arr[largest], arr[i]  # 交换
        heapify(arr, n, largest) #递归地对交换后的子树调用heapify函数,以保持堆的性质
#函数目的:使用堆排序算法对数组进行排序
def heap_sort(arr):
    n = len(arr)#计算数组的长度
#对数组进行从上到下,从最后一个非叶子节点开始调整,保证符合堆的性质
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)
#对数组进行从上到下排序,每次取出最大值放到数组的末尾
    for i in range(n-1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i] #交换
        heapify(arr, i, 0)
    return arr
    
        
if __name__ == '__main__':
    arr = [5, 7, 3, 7, 2, 3, 2, 5, 9, 5, 7, 8]
    print(heap_sort(arr))

(3)算法分析

时间复杂度:最佳情况下,堆排序的时间复杂度为 O(nlogn)。在最坏情况下,如果输入数组已经是有序的,其时间复杂度退化为 O(n^2)。

空间复杂度:堆排序是原地排序算法,不需要额外的存储空间,因此其空间复杂度为 O(1)。

稳定性:堆排序是稳定的排序算法,因为相等的元素在交换过程中不会被交换。

适用场景:对于处理中小规模数据集的排序场景,堆排序是一个高效的选择。但对于大规模数据集或者含有大量重复元素的数组,其他排序算法如归并排序或快速排序可能更为合适。

局限性:由于堆排序需要构建和调整堆,因此对于非常大的数组,可能会占用大量内存。此外,如果输入数据不满足堆的性质,排序结果可能不正确。

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值