-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap_topk.py
71 lines (60 loc) · 1.82 KB
/
heap_topk.py
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# -*- coding: utf-8 -*-
# created by Frank Jiang on 2020/8/11 15:09
import random
def sift(li, low, high):
"""
:param li: 列表
:param low: 堆的根节点位置
:param high: 堆的最后一个元素的位置
:return:
sift时间复杂度:O(logn)
"""
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: # 如果j位置的值小于堆顶元素
li[i] = li[j] # 将j位置的值赋给i位置
i = j # 往下看一层
j = 2 * i + 1 # 下一层的孩子
else: # tmp更大,把tmp放到i的位置上
li[i] = tmp # 把tmp放到某一级领导位置上
break
else:
li[i] = tmp # 把tmp放到叶子节点上
def top_k(li, k):
heap = li[0:k]
for i in range((k - 2) // 2, -1, -1):
sift(heap, i, k - 1)
# 建堆
for i in range(k, len(li) - 1):
if li[i] > heap[0]:
heap[0] = li[i]
sift(heap, 0, k - 1)
# 遍历
for i in range(k - 1, 0, -1):
# i 指向当前堆的最后一个元素
heap[0], heap[i] = heap[i], heap[0]
sift(heap, 0, i - 1)
# 出数
return heap
li = list(range(100))
random.shuffle(li)
print(top_k(li, 10))
def heap_sort(li):
"""
:param li: 待排序的列表
:return:
heap_sort时间复杂度:
"""
n = len(li)
for i in range((n - 2) // 2, -1, -1):
# i表示建堆的时候调整的部分的根的下标
sift(li, i, n - 1)
# 建堆完成
for i in range(n - 1, 0, -1):
# i 指向当前堆的最后一个元素
li[0], li[i] = li[i], li[0]
sift(li, 0, i - 1)