堆排序的原理及python实现
Posted python进阶和MySQL技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序的原理及python实现相关的知识,希望对你有一定的参考价值。
堆排序步骤:
1、建(大)堆(顶部为最大元素,堆叶子节点元素不大于它的顶元素)
2、依次把堆顶元素交换到最后,重建堆顶(堆不包含刚交换的最大元素)
对于节点k来说,它的左右叶子节点位置分别为2k+1, 2k+2
"""
堆排序步骤:
1、建(大)堆(顶部为最大元素,堆叶子节点元素不大于它的顶元素)
2、依次把堆顶元素交换到最后,重建堆顶(堆不包含刚交换的最大元素)
下面为堆节点对应在list中的位置
0
1 2
3 4 5 6
7 8 9 10 11 12 13 14
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
对于节点k来说,它的左右叶子节点位置分别为2k+1, 2k+2
author: 村边河水流
date: 2019-8-21
LICENSE: 转载请注明作者及来源
"""
from time import time
from random import shuffle
def heap_sort(array: list):
n = len(array)
# 从尾部开始建堆,这样保证子节点有序
for i in range((n-1)//2, -1, -1):
_shift(array, n, i)
# 依次把堆顶元素交换到最后,重建堆顶(堆不包含刚交换的最大元素)
for i in range(n-1, 0, -1):
array[0], array[i] = array[i], array[0]
_shift(array, i, 0)
# 重建堆顶元素 n:堆元素个数,i:堆建顶位置
def _shift(array: list, n: int, i: int):
# 如果没有子节点,直接返回
if i*2+1 >= n:
return
# 取最大子节点位置
maxsub = i*2+2 if i*2+2 < n and array[i*2+1] <= array[i*2+2] else i*2+1
# 如果节点小于最大子节点,交换元素,递归以子节点为堆顶重建
if array[i] < array[maxsub]:
array[i], array[maxsub] = array[maxsub], array[i]
_shift(array, n, maxsub)
def main():
n = 50000
nums = list(range(n))
shuffle(nums)
li = nums.copy()
t1 = time()
heap_sort(li)
print(f"堆排序算法需要时间 {time() - t1}s")
assert(li == list(range(n)))
if __name__ == '__main__':
main()
以上是关于堆排序的原理及python实现的主要内容,如果未能解决你的问题,请参考以下文章
常见排序算法基本原理及实现(快排,归并,堆排,直接插入.....)
常见排序算法基本原理及实现(快排,归并,堆排,直接插入.....)