排序-堆

堆排序:堆是具有以下性质的完全二叉树:
每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;
或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

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

python代码实现:
import math

#i表示在列表中的实际位置,求i位置的父节点:n=(i-1)/2,然后向下取整,根从0开始计数
def heapify(arr, i):
    largest = i
    while i > 0 :
        #求i位置的父节点位置
        n = math.floor((i-1)/2)
        #根据公式求左右孩子节点的位置
        l = 2 * n + 1  # left = 2*i + 1
        r = 2 * n + 2  # right = 2*i + 2
        #如果父节点小于左孩子,并且左孩子的位置小于等于largest的值,则交换值
        if l <= largest and arr[n]<arr[l] :
            arr[n],arr[l] = arr[l],arr[n]
        #如果父节点小于右孩子,则交换值
        if r <= largest and arr[n]<arr[r] :
            arr[n],arr[r] = arr[r],arr[n]
        i = i - 2
    #i位置与0位置的最大值互换值
    arr[largest],arr[0] = arr[0],arr[largest]


def heapSort(arr):
    n = len(arr)
    #建造完美二叉树初始list:7 4 1 2 6 5 3
    #                      0 1 2 3 4 5 6
    #先从6位置开始找,依次递减0,直到1位置即完成排序
    for i in range(n-1, 0, -1):
        heapify(arr,i)

def main():
    data = list(map(int,input("请输入需要排序的列表,逗号间隔:").split(",")))
    #7,4,1,2,6,5,3
    #7,4,1,2,6,8
    heapSort(data)
    print("堆排序结果为:", end="")
    print(data)
if __name__ == "__main__":
    main()

 

 
posted @ 2020-03-22 21:34  StudyNLP  阅读(212)  评论(0编辑  收藏  举报