Python 实现堆排序

(二叉)堆
它是一个数组,可以被看成一个完全二叉树
A.length = 数组元素的个数
A.heap_size = 堆元素的个数
父结点 parent(i) : return(i//2)
左结点 left(i) : return 2*i

右结点 right(i) : return(2*i + 1)



最大堆:A[parent(i)] >= A[i] 最大值存于根结点
最小堆:A[parent(i)] <= A[i] 最小值存于根结点
除了根结点,都满足以上性质
堆排序使用的是最大堆,最小堆通常用于构造优先队列。


堆排序
1.建堆:使堆中的每个结点都满足最大堆原则
2.保存最大堆:比较结点与其子结点的大小,将最大元素换到该结点的位置
3.堆排序:将最大元素与队尾元素交换,再将堆长度减一,保持现有堆的最大堆性质,直到排序完成

堆排序的时间复杂度由 init 与 sort 组成其中:
init : O(n)    sort : O(n*logn)

其在排序小容量的数组时,用在初始化上的时间较多

# !/usr/bin/env python3
# -*- code:utf-8 -*-
'''max_heapify.py  2018年6月13日
实现堆排序的步骤:
1.保证结点满足最大堆性质
2.使用性质建立堆
3.将A[0] 最大元素移动到队尾,堆大小减一,循环至排序完成'''
from numpy.random import randint


def Left(i):
    return 2*i + 1


def Parent(i):
    return (i-1)//2


def Right(i):
    return 2*i + 2


def ShowHeap(A):
    A_len = len(A)
    layer = 0
    while A_len > 0:
        A_len >>= 1
        layer += 1
    for i in range(0, layer-1):
        temp = str([A[j] for j in range(2**i-1, 2**(i+1)-1)])
        print(str((layer-i)*2*' ') + temp)
    print(A[2**(layer-1)-1:])


def MaxHeapify(A, i):
    l = Left(i)
    r = Right(i)
    if l < len(A) and A[l] > A[i]:
        largest = l
    else:
        largest = i
    if r < len(A) and A[r] > A[largest]:
        largest = r
    if largest != i:
        A[i], A[largest] = A[largest], A[i]
        MaxHeapify(A, largest)
    return A


def BuildHeap(A):
    for i in range(len(A)//2, -1, -1):
        MaxHeapify(A, i)
    return A


def HeapSort(A):
    BuildHeap(A)
    #ShowHeap(A)
    temp = []
    for i in range(len(A)-1, -1, -1):
        A[0], A[i] = A[i], A[0]
        temp.append(A[i])
        A = MaxHeapify(A[:i], 0)
    return temp


# 验证
if __name__ == '__main__':
    A = list(randint(1, 100, 15))
    print(A)
    A = HeapSort(A)
    print(A)




阅读更多
文章标签: 算法 Python
个人分类: 算法导论
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭