堆排序
堆排序
学习来源:b站 python分享站
堆排序的过程:
1、建立堆。
2、得到堆顶元素,为最大元素
3、去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。
4、堆顶元素为第二大元素。
5、重复步骤3,直到堆变空。
代码:
import random
# 堆排序
def sift(li, low, high):
"""
:param li: 列表
:param low: 堆的根节点位置
:param high: 堆的最后一个元素的位置
:return:
"""
i = low # 最开始指向根节点
j = 2 * i + 1 # j开始是左孩子
tmp = li[low] # 把堆顶存起来
while j <= high: # 只要j位置有数
if j + 1 <= high and li[j + 1] > li[j]: # 如果右孩子有且比较大
j = j + 1 # j指向右孩子
if li[j] > tmp:
li[i] = li[j]
i = j
j = 2 * i + 1
else: # tmp更大, 把tmp放到i位置上
li[i] = tmp # 把tmp放到某一级领导位置上
break
else:
li[i] = tmp # 把tmp放到叶子节点上
def heap_sort(li):
n = len(li)
for i in range((n - 2) // 2, -1, -1):
# i表示建堆的时候调整的部分的根的下标
sift(li, i, n - 1)
# 建堆完成
for i in range(n - 1, -1, -1):
# i指向当前堆的最后一个元素
li[0], li[i] = li[i], li[0]
sift(li, 0, i - 1) # i-1是新的high
li = [i for i in range(100)]
random.shuffle(li)
print(li)
heap_sort(li)
print(li)
用python内置模块实现堆排序,代码如下:
# 内置模块 --- 堆排序
import heapq
import random
li = list(range(100))
random.shuffle(li)
print(li)
heapq.heapify(li) # 建堆
n = len(li)
for i in range(n):
print(heapq.heappop(li), end=',') # 每次弹出最小值
堆排序的topk问题
解决思路:
1、取列表前k个元素建立一个小根堆。堆顶就是目前第k大的数。
2、依次向后遍历原列表,对于列表中的元素,如果小于堆顶,则忽略该元素;如果大于堆顶,则将堆顶更换为该元素,并且对堆进行一次调整。
3、遍历列表所有元素后,倒序弹出堆顶。
代码:
import random
# 堆排序
def sift(li, low, high):
"""
:param li: 列表
:param low: 堆的根节点位置
:param high: 堆的最后一个元素的位置
:return:
"""
i = low # 最开始指向根节点
j = 2 * i + 1 # j开始是左孩子
tmp = li[low] # 把堆顶存起来
while j <= high: # 只要j位置有数
if j + 1 <= high and li[j + 1] < li[j]: # 如果右孩子有且比较小
j = j + 1 # j指向右孩子
if li[j] < tmp:
li[i] = li[j]
i = j
j = 2 * i + 1
else: # tmp更小, 把tmp放到i位置上
li[i] = tmp # 把tmp放到某一级领导位置上
break
else:
li[i] = tmp # 把tmp放到叶子节点上
def topk(li, k):
heap = li[0:k]
for i in range((k - 2) // 2, -1, -1):
# i表示建堆的时候调整的部分的根的下标
sift(heap, i, k - 1)
# 1.建堆完成
for i in range(k, len(li) - 1):
if li[i] > heap[0]:
heap[0] = li[i]
sift(heap, 0, k-1)
# 2.遍历
for i in range(k-1, -1, -1):
# i指向当前堆的最后一个元素
heap[0], heap[i] = heap[i], heap[0]
sift(heap, 0, i - 1) # i-1是新的high
# 3.出数
return heap
li = list(range(100))
random.shuffle(li)
print(topk(li, 10))