Python笔记 之 堆排序

使用使用Python实现堆排序算法(最大堆算法)

算法的时间复杂度表示为: O ( n lg ⁡ n ) O(n\lg{n}) O(nlgn)

最大堆排序算法伪算法如下:

'''
(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树。
树上的每一个节点对应数组中的一个元素。
除了最底层外,该树是一个完全充满的,而且是从左向右完全填充的。
树的一个节点A[i],它的父结点,左孩子,右孩子下标(如果存在)分别是:
PARENT=⌊i/2⌋
LEFT=2i
RIGHT=2i+1

max_Heapify(A,i)
    l=LEFT(i)
    r=RIGHT(i)
    if l<=A.heap-size and A[l]>A[i]
        largest=l
    else largest=i
    if r<=A.heap-size and A[r]>A[i]
        largets=r
    if largest!=i
        exchange A[i] with A[largest]
    max_heapify(A,largest)

build_Max_Heapify(A)
    A.heap-size=A.length
    for i=⌊A.length/2⌋ downto 1
        max_Heapify(A,i)

heap_Sort(A)
    build_Max_Heapify(A)
    for i=A.length down to 2
        exchange A[1] with A[i]
        A.heap-size = A.heap-size-1
        max_Heapify(A,1)
    
'''

最大堆排序Python算法:

import math
def max_Heapify(A,heapsize,rootid):
    """
    递归调用将以rootid为根子树转换为最大堆
    数组应该是全序集合
    Python数组的起始位为0,堆的根节点为1,rootid由数组到堆转换时应加1处理
    """
    leftleaf=(rootid+1)*2
    left=leftleaf-1
    rightleaf=(rootid+1)*2+1
    right=rightleaf-1
    if leftleaf<=heapsize and A[left]>A[rootid]:
        largest=left
    else:
        largest=rootid
    if rightleaf<=heapsize and A[right]>A[largest]:
        largest=right
    if largest != rootid:
        A[rootid],A[largest]=A[largest],A[rootid]
        max_Heapify(A,heapsize,largest)
    return A
def build_Max_Heap(A):
    """循环调用max_Heapify,将一维数组转换为最大堆"""
    heapsize=len(A)
    for i in range(math.ceil(heapsize/2),-1,-1):
        max_Heapify(A,heapsize,i)
    return A
def heap_Sort(A):
    """
    调用build_Max_Heap,将一维数组转换为最大堆
    依次取最大堆的根节点,完成排序
    """
    build_Max_Heap(A)
    length=len(A)-1
    size=len(A)
    for i in range(length,0,-1):
        A[0],A[i]=A[i],A[0]
        size=size-1
        max_Heapify(A,size,0)
    return A

运行结果

a=[13,13,12,11,10,8,9,5,6,7,3,4,2,1,0]
print(a)
print(heap_Sort(a))
[13, 13, 12, 11, 10, 8, 9, 5, 6, 7, 3, 4, 2, 1, 0]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值