-
Notifications
You must be signed in to change notification settings - Fork 0
/
heap.py
103 lines (90 loc) · 2.83 KB
/
heap.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""
通常指二叉堆,是近似完全二叉树的数据结构
常被用作实现优先队列
"""
class MaxHeap(object):
def __init__(self, array=None):
if array:
self.heap = self._max_heapify(array)
else:
self.heap = []
def _sink(self, array, i):
left = i*2 + 1
right = i*2 + 2
max_index = i
if left < len(array) and array[left] > array[max_index]:
max_index = left
if right < len(array) and array[right] > array[max_index]:
max_index = right
if max_index != i:
array[i], array[max_index] = array[max_index], array[i]
self._sink(array, max_index)
def _swim(self, array, i):
if i == 0:
return
father = (i-1)/2
if array[father] < array[i]:
array[father], array[i] = array[i], array[father]
self._swim(array, father)
def _max_heapify(self, array):
for i in xrange(len(array) / 2, -1, -1):
self._sink(array, i)
return array
def push(self, item):
self.heap.append(item)
self.swim(self.heap, len(self.heap) - 1)
def pop(self):
self.heap[0], self.heap[-1] = self.heap[-1], self.heap[0]
item = self.heap.pop()
self._sink(self.heap, 0)
return item
HEAP_SIZE = 0
LEFT = lambda i: i*2+1
RIGHT = lambda i: i*2+2
# 保持大根堆
def heapify(alist, i):
l, r = LEFT, RIGHT
max_index = i
if l < len(alist) and alist[l] > alist[max_index]:
max_index = l
if r < len(alist) and alist[r] > alist[max_index]:
max_index = r
if max_index != i:
alist[i], alist[max_index] = alist[i], alist[max_index]
heapify(alist, max_index)
# 创建大根堆
def build_max_heap(alist):
for i in xrange(len(alist)//2 - 1, -1, -1):
heapify(alist, i)
# heap sort
def heap_sort(alist):
"""
移除根节点,并做最大堆调整递归
"""
# 最后一个父节点, 下标从0开始
first = len(alist) // 2 - 1
for start in xrange(first, -1, -1):
# 开始构造大根堆
max_heapify(alist, start, len(alist)-1)
for end in xrange(len(alist)-1, 0, -1): # heap sort
alist[end], alist[0] = alist[0], alist[end]
max_heapify(alist, 0, end-1)
return alist
def max_heapify(array, start, end):
"""
大根堆调整,调整子节点,总是小于父节点
"""
root = start
while True:
child = root*2 + 1
if child > end:
break
if child+1 <= end and array[child] < array[child+1]:
child = child + 1
if array[root] < array[child]: # 大的子节点成为父节点
array[root], array[child] = array[child], array[root]
root = child
else:
break