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