Skip to content

Commit a5f8fe0

Browse files
author
ssjssh
committed
斐波那契树完成插入和extra_min
1 parent ffcb064 commit a5f8fe0

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

src/ssj/heap/fibonacci_heap.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#!/usr/bin/env python
2+
# -*- coding:UTF-8
3+
__author__ = 'shenshijun'
4+
5+
6+
class FibonacciHeap(object):
7+
"""实现斐波那契堆,斐波那契堆在一些操作执行的时候负责度比较低,而其他操作的复杂度和普通的堆是一样的"""
8+
9+
class Node(object):
10+
"""节点实现"""
11+
12+
def __init__(self, key, parent=None, child=None, left=None, right=None):
13+
"""Constructor for """
14+
self.key = key
15+
self.degree = 0
16+
self.mark = False
17+
self.parent = parent
18+
self.child = child
19+
self.left = left or self
20+
self.right = right or self
21+
22+
def __str__(self):
23+
return str(self.key) + " : " + str(self.degree)
24+
25+
def __init__(self, *argv):
26+
"""Constructor for """
27+
self.__root = None
28+
self.__size = 0
29+
map(self.insert, argv)
30+
31+
def insert(self, key):
32+
self.__size += 1
33+
if self.__root is None:
34+
self.__root = self.Node(key)
35+
else:
36+
new_node = self.Node(key, left=self.__root.left, right=self.__root)
37+
self.__root.left.right = new_node
38+
self.__root.left = new_node
39+
if new_node.key < self.__root.key:
40+
self.__root = new_node
41+
42+
def extract_min(self):
43+
if self.__root is None:
44+
return None
45+
46+
result = self.__root
47+
self.__size -= 1
48+
49+
# 首先把根节点的子节点全部移到根链表上
50+
child = self.__root.child
51+
for i in xrange(0, self.__root.degree):
52+
next_node = child.right
53+
self.__root.left.right = child
54+
child.left = self.__root.left
55+
self.__root.left = child
56+
child.right = self.__root
57+
child.parent = None
58+
child = next_node
59+
60+
# 移除根节点
61+
self.__root.left.right = self.__root.right
62+
self.__root.right.left = self.__root.left
63+
if self.__root.right is self.__root:
64+
self.__root = None
65+
else:
66+
self.__root = self.__root.right
67+
self.__extract_consolidating()
68+
69+
return result.key
70+
71+
def __extract_consolidating(self):
72+
# 合并根链表
73+
node_degrees = {}
74+
pass_root = False
75+
cur_node = self.__root
76+
after_merge = False
77+
next_node = None
78+
while cur_node is not self.__root or not pass_root or after_merge:
79+
if cur_node == self.__root:
80+
pass_root = True
81+
82+
if not after_merge:
83+
next_node = cur_node.right
84+
85+
d = cur_node.degree
86+
if d in node_degrees:
87+
other_node = node_degrees[d]
88+
sm_node = cur_node if cur_node.key <= other_node.key else other_node
89+
bg_node = cur_node if cur_node.key > other_node.key else other_node
90+
# 把大的节点连接到小的节点上面,然后继续在sm_node上面循环,因为sm_node的度数发生了变化
91+
self.__link_to(bg_node, sm_node)
92+
del node_degrees[d]
93+
after_merge = True
94+
cur_node = sm_node
95+
else:
96+
after_merge = False
97+
node_degrees[d] = cur_node
98+
cur_node = next_node
99+
100+
self.__root = None
101+
102+
for d, node in node_degrees.iteritems():
103+
node.parent = None
104+
if self.__root is None:
105+
self.__root = node
106+
self.__root.left = node
107+
self.__root.right = node
108+
else:
109+
node.left = self.__root.left
110+
node.right = self.__root
111+
self.__root.left.right = node
112+
self.__root.left = node
113+
114+
if self.__root.key > node.key:
115+
self.__root = node
116+
117+
@staticmethod
118+
def __link_to(src, dest):
119+
"""
120+
bugfix: 不能把src从根链表移除,这样的话会破坏根链表,导致在__extract_consolidating中的while找不到退出条件
121+
我是为了避免重新创建根链表而把src从根链表中移除,这段注释只是为了提醒
122+
:param src:
123+
:param dest:
124+
:return:
125+
"""
126+
src.mark = False
127+
128+
dest_child = dest.child
129+
src.parent = dest
130+
if dest_child is None:
131+
dest.child = src
132+
src.left = src
133+
src.right = src
134+
else:
135+
src.left = dest_child.left
136+
dest_child.left.right = src
137+
dest_child.left = src
138+
src.right = dest_child
139+
dest.degree += 1
140+
141+
def union(self, other):
142+
pass
143+
144+
def min(self):
145+
return None if self.__root is None else self.__root.key
146+
147+
def change_key(self, node, new_key):
148+
pass
149+
150+
def __len__(self):
151+
return self.__size
152+
153+
def delete(self, node):
154+
self.change_key(node, float('-Inf'))
155+
self.extract_min()
156+
157+
158+
def main():
159+
test = ['O', 'J', 'S', 'Y', 'C', 'M', 'B', 'R', 'N', 'F', 'L', 'Z', 'U', 'Q', 'A', 'G', 'V', 'E', 'D', 'W', 'I',
160+
'H', 'T', 'K', 'X', 'P']
161+
162+
heap = FibonacciHeap(*test)
163+
for i in xrange(0, len(heap)):
164+
print(heap.extract_min())
165+
166+
167+
if __name__ == "__main__":
168+
main()

0 commit comments

Comments
 (0)