Skip to content

Commit cb5f092

Browse files
committed
python中的二叉树模块
1 parent 7ab899b commit cb5f092

File tree

1 file changed

+379
-0
lines changed

1 file changed

+379
-0
lines changed

binary_tree_python.md

Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
#问题
2+
3+
Python中的二叉树查找算法模块
4+
5+
#思路说明
6+
7+
二叉树查找算法,在开发实践中,会经常用到。按照惯例,对于这么一个常用的东西,Python一定会提供轮子的。是的,python就是这样,一定会让开发者省心,降低开发者的工作压力。
8+
9+
python中的二叉树模块内容:
10+
11+
- BinaryTree:非平衡二叉树
12+
- AVLTree:平衡的AVL树
13+
- RBTree:平衡的红黑树
14+
15+
以上是用python写的,相面的模块是用c写的,并且可以做为Cython的包。
16+
17+
- FastBinaryTree
18+
- FastAVLTree
19+
- FastRBTree
20+
21+
**特别需要说明的是:树往往要比python内置的dict类慢一些,但是它中的所有数据都是按照某个关键词进行排序的,故在某些情况下是必须使用的。**
22+
23+
#安装和使用
24+
25+
##安装方法
26+
27+
###安装环境:
28+
29+
ubuntu12.04, python 2.7.6
30+
31+
###安装方法
32+
33+
- 下载源码,地址:https://bitbucket.org/mozman/bintrees/src
34+
- 进入源码目录,看到setup.py文件,在该目录内运行
35+
36+
python setup.py install
37+
38+
安装成功,ok!下面就看如何使用了。
39+
40+
###应用
41+
42+
bintrees提供了丰富的API,涵盖了通常的多种应用。下面逐条说明其应用。
43+
44+
- 引用
45+
46+
如果按照一般模块的思路,输入下面的命令引入上述模块
47+
48+
>>> import bintrees
49+
50+
错了,这是错的,出现如下警告:(×××不可用,用×××)
51+
52+
Warning: FastBinaryTree not available, using Python version BinaryTree.
53+
Warning: FastAVLTree not available, using Python version AVLTree.
54+
Warning: FastRBTree not available, using Python version RBTree.
55+
56+
正确的引入方式是:
57+
58+
>>> from bintrees import BinaryTree #只引入了BinartTree
59+
>>> from bintrees import * #三个模块都引入了
60+
61+
- 实例化
62+
63+
>>> btree = BinaryTree()
64+
>>> btree
65+
BinaryTree({})
66+
>>> type(btree)
67+
<class 'bintrees.bintree.BinaryTree'>
68+
69+
- 逐个增加键值对:.__setitem__(k,v) .复杂度O(log(n))(后续说明中,都会有复杂度标示,为了简单,直接标明:O(log(n)).)
70+
71+
>>> btree.__setitem__("Tom","headmaster")
72+
>>> btree
73+
BinaryTree({'Tom': 'headmaster'})
74+
>>> btree.__setitem__("blog","http://blog.csdn.net/qiwsir")
75+
>>> btree
76+
BinaryTree({'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
77+
78+
- 批量添加:.update(E) E是dict/iterable,将E批量更新入btree. O(E*log(n))
79+
80+
>>> adict = [(2,"phone"),(5,"tea"),(9,"scree"),(7,"computer")]
81+
>>> btree.update(adict)
82+
>>> btree
83+
BinaryTree({2: 'phone', 5: 'tea', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
84+
85+
- 查找某个key是否存在:.__contains__(k) 如果含有键k,则返回True,否则返回False. O(log(n))
86+
87+
>>> btree
88+
BinaryTree({2: 'phone', 5: 'tea', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
89+
>>> btree.__contains__(5)
90+
True
91+
>>> btree.__contains__("blog")
92+
True
93+
>>> btree.__contains__("qiwsir")
94+
False
95+
>>> btree.__contains__(1)
96+
False
97+
98+
- 根据key删除某个key-value:.__delitem__(key), O(log(n))
99+
100+
>>> btree
101+
BinaryTree({2: 'phone', 5: 'tea', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
102+
>>> btree.__delitem__(5) #删除key=5的key-value,即:5:'tea' 被删除.
103+
>>> btree
104+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
105+
106+
- 根据key值得到该kye的value:.__getitem__(key)
107+
108+
>>> btree
109+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
110+
>>> btree.__getitem__("blog")
111+
'http://blog.csdn.net/qiwsir'
112+
>>> btree.__getitem__(7)
113+
'computer'
114+
>>> btree._getitem__(5) #在btree中没有key=5,于是报错。
115+
Traceback (most recent call last):
116+
File "<stdin>", line 1, in <module>
117+
AttributeError: 'BinaryTree' object has no attribute '_getitem__'
118+
119+
- 迭代器:.__iter__()
120+
121+
>>> btree
122+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
123+
>>> aiter = btree.__iter__()
124+
>>> aiter
125+
<generator object <genexpr> at 0xb7416dec>
126+
>>> aiter.next() #注意:next()一个之后,该值从list中删除
127+
2
128+
>>> aiter.next()
129+
7
130+
>>> list(aiter)
131+
[9, 'Tom', 'blog']
132+
>>> list(aiter) #结果是空
133+
[]
134+
>>> bool(aiter) #but,is True
135+
True
136+
137+
- 数的数据长度:.__len__(),返回btree的长度。O(1)
138+
139+
>>> btree
140+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
141+
>>> btree.__len__()
142+
5
143+
144+
- 找出key最大的k-v对:.__max__(),按照key排列,返回key最大的键值对。
145+
146+
- 找出key最小的键值对:.__min__()
147+
148+
>>> btree
149+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
150+
>>> btree.__max__()
151+
(9, 'scree')
152+
>>> btree.__min__()
153+
(2, 'phone')
154+
155+
- 两棵树的关系运算
156+
157+
>>> other = [(3,'http://blog.csdn.net/qiwsir'),(7,'qiwsir')]
158+
>>> bother = BinaryTree() #再建一个树
159+
>>> bother.update(other) #加入数据
160+
161+
>>> bother
162+
BinaryTree({3: 'http://blog.csdn.net/qiwsir', 7: 'qiwsir'})
163+
>>> btree
164+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
165+
166+
>>> btree.__and__(bother) #重叠部分部分
167+
BinaryTree({7: 'computer'})
168+
169+
>>> btree.__or__(bother) #全部
170+
BinaryTree({2: 'phone', 3: 'http://blog.csdn.net/qiwsir', 7: 'computer', 9: 'scree'})
171+
172+
>>> btree.__sub__(bother) #btree不与bother重叠的部分
173+
BinaryTree({2: 'phone', 9: 'scree'})
174+
175+
>>> btree.__xor__(bother) #两者非重叠部分
176+
BinaryTree({2: 'phone', 3: 'http://blog.csdn.net/qiwsir', 9: 'scree'})
177+
178+
- 输出字符串模样,注意仅仅是输出的模样罢了:.__repr__()
179+
180+
>>> btree
181+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
182+
>>> btree.__repr__()
183+
"BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})"
184+
185+
- 清空树中的所有数据:.clear(),O(log(n))
186+
187+
>>> bother
188+
BinaryTree({3: 'http://blog.csdn.net/qiwsir', 7: 'qiwsir'})
189+
>>> bother.clear()
190+
>>> bother
191+
BinaryTree({})
192+
>>> bool(bother)
193+
False
194+
195+
- 浅拷贝:.copy(),官方文档上说是浅拷贝,但是我做了操作实现,是下面所示,还不是很理解其“浅”的含义。O(n*log(n))
196+
197+
>>> btree
198+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
199+
>>> ctree = btree.copy()
200+
>>> ctree
201+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
202+
203+
>>> btree.__setitem__("github","qiwsir") #增加btree的数据
204+
>>> btree
205+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
206+
>>> ctree
207+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'}) #这是不是在说明属于深拷贝呢?
208+
209+
>>> ctree.__delitem__(7) #删除ctree的一个数据
210+
>>> ctree
211+
BinaryTree({2: 'phone', 9: 'scree'})
212+
>>> btree
213+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
214+
215+
- 移除树中的一个数据:.discard(key),这个功能与.__delitem__(key)类似.两者都不反悔值。O(log(n))
216+
217+
>>> ctree
218+
BinaryTree({2: 'phone', 9: 'scree'})
219+
>>> ctree.discard(2) #删除后,不返回值,或者返回None
220+
>>> ctree
221+
BinaryTree({9: 'scree'})
222+
>>> ctree.discard(2) #如果删除的key不存在,也返回None
223+
>>> ctree.discard(3)
224+
>>> ctree.__delitem__(3) #但是,.__delitem__(key)则不同,如果key不存在,会报错。
225+
Traceback (most recent call last):
226+
File "<stdin>", line 1, in <module>
227+
File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 264, in __delitem__
228+
self.remove(key)
229+
File "/usr/local/lib/python2.7/site-packages/bintrees/bintree.py", line 124, in remove
230+
raise KeyError(str(key))
231+
KeyError: '3'
232+
233+
- 根据key查找,并返回或返回备用值:.get(key[,d])。如果key在树中存在,则返回value,否则如果有d,则返回d值。O(log(n))
234+
235+
>>> btree
236+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
237+
>>> btree.get(2,"algorithm")
238+
'phone'
239+
>>> btree.get("python","algorithm") #没有key='python'的值,返回'algorithm'
240+
'algorithm'
241+
>>> btree.get("python") #如果不指定第二个参数,若查不到,则返回None
242+
>>>
243+
244+
- 判断树是否为空:is_empty().根据树数据的长度,如果数据长度为0,则为空。O(1)
245+
246+
>>> ctree
247+
BinaryTree({9: 'scree'})
248+
>>> ctree.clear() #清空数据
249+
>>> ctree
250+
BinaryTree({})
251+
>>> ctree.is_empty()
252+
True
253+
>>> btree
254+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
255+
>>> btree.is_empty()
256+
False
257+
258+
- 根据key、value循环从树中取值:
259+
260+
>>.items([reverse])--按照(key,value)结构取值;
261+
>>.keys([reverse])--key
262+
>>.values([reverse])--value. O(n)
263+
>>.iter_items(s,e[,reverse]--s,e是key的范围,也就是生成在某个范围内的key的迭代器 O(n)
264+
265+
>>> btree
266+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
267+
>>> for (k,v) in btree.items():
268+
... print k,v
269+
...
270+
2 phone
271+
7 computer
272+
9 scree
273+
github qiwsir
274+
>>> for k in btree.keys():
275+
... print k
276+
...
277+
2
278+
7
279+
9
280+
github
281+
>>> for v in btree.values():
282+
... print v
283+
...
284+
phone
285+
computer
286+
scree
287+
qiwsir
288+
>>> for (k,v) in btree.items(reverse=True): #反序
289+
... print k,v
290+
...
291+
github qiwsir
292+
9 scree
293+
7 computer
294+
2 phone
295+
296+
>>> btree
297+
BinaryTree({2: 'phone', 5: None, 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
298+
>>> for (k,v) in btree.iter_items(6,9): #要求迭代6<=key<9的键值对数据
299+
... print k,v
300+
...
301+
7 computer
302+
8 eight
303+
>>>
304+
305+
306+
- 删除数据并返回该值:
307+
308+
>>.pop(key[,d]), 根据key删除树的数据,并返回该value,但是如果没有,并也指定了备选返回的d,则返回d,如果没有d,则报错;
309+
>>.pop_item(),在树中随机选择(key,value)删除,并返回。
310+
311+
>>> ctree = btree.copy()
312+
>>> ctree
313+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
314+
315+
>>> ctree.pop(2) #删除key=2的数据,返回其value
316+
'phone'
317+
>>> ctree.pop(2) #删除一个不存在的key,报错
318+
Traceback (most recent call last):
319+
File "<stdin>", line 1, in <module>
320+
File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 350, in pop
321+
value = self.get_value(key)
322+
File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 557, in get_value
323+
raise KeyError(str(key))
324+
KeyError: '2'
325+
326+
>>> ctree.pop_item() #随机返回一个(key,value),并已删除之
327+
(7, 'computer')
328+
>>> ctree
329+
BinaryTree({9: 'scree', 'github': 'qiwsir'})
330+
331+
>>> ctree.pop(7,"sing") #如果没有,可以返回指定值
332+
'sing'
333+
334+
- 查找数据,并返回value:.set_default(key[,d]),在树的数据中查找key,如果存在,则返回该value。如果不存在,当指定了d,则将该(key,d)添加到树内;当不指定d的时候,添加(key,None). O(log(n))
335+
336+
>>> btree
337+
BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
338+
>>> btree.set_default(7) #存在则返回
339+
'computer'
340+
341+
>>> btree.set_default(8,"eight") #不存在,则返回后备指定值,并加入到树
342+
'eight'
343+
>>> btree
344+
BinaryTree({2: 'phone', 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
345+
346+
>>> btree.set_default(5) #如果不指定值,则会加入None
347+
>>> btree
348+
BinaryTree({2: 'phone', 5: None, 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
349+
350+
>>> btree.get(2) #注意,.get(key)与.set_default(key[,d])的区别
351+
'phone'
352+
>>> btree.get(3,"mobile") #不存在的 key,返回但不增加到树
353+
'mobile'
354+
>>> btree
355+
BinaryTree({2: 'phone', 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
356+
357+
- 根据key删除值
358+
359+
>>.remove(key),删除(key,value)
360+
>>.remove_items(keys),keys是一个key组成的list,逐个删除树中的对应数据
361+
362+
>>> ctree
363+
BinaryTree({2: 'phone', 5: None, 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
364+
>>> ctree.remove_items([5,6]) #key=6,不存在,报错
365+
Traceback (most recent call last):
366+
File "<stdin>", line 1, in <module>
367+
File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 271, in remove_items
368+
self.remove(key)
369+
File "/usr/local/lib/python2.7/site-packages/bintrees/bintree.py", line 124, in remove
370+
raise KeyError(str(key))
371+
KeyError: '6'
372+
373+
>>> ctree
374+
BinaryTree({2: 'phone', 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
375+
>>> ctree.remove_items([2,7,'github']) #按照 列表中顺序逐个删除
376+
>>> ctree
377+
BinaryTree({8: 'eight', 9: 'scree'})
378+
379+
###以上只是入门的基本方法啦,还有更多内容,请移不到到文章开头的官方网站。

0 commit comments

Comments
 (0)