Python中的二叉树查找算法模块使用指南


Posted in Python onJuly 04, 2014

python中的二叉树模块内容:

BinaryTree:非平衡二叉树
 AVLTree:平衡的AVL树
 RBTree:平衡的红黑树
以上是用python写的,相面的模块是用c写的,并且可以做为Cython的包。

FastBinaryTree
 FastAVLTree
 FastRBTree
特别需要说明的是:树往往要比python内置的dict类慢一些,但是它中的所有数据都是按照某个关键词进行排序的,故在某些情况下是必须使用的。

安装和使用

安装方法

安装环境:

ubuntu12.04, python 2.7.6

安装方法

下载源码,地址:https://bitbucket.org/mozman/bintrees/src
进入源码目录,看到setup.py文件,在该目录内运行   

python setup.py install

安装成功,ok!下面就看如何使用了。

应用

bintrees提供了丰富的API,涵盖了通常的多种应用。下面逐条说明其应用。

- 引用

如果按照一般模块的思路,输入下面的命令引入上述模块

>>> import bintrees

 
错了,这是错的,出现如下警告:(×××不可用,用×××)

Warning: FastBinaryTree not available, using Python version BinaryTree.

  Warning: FastAVLTree not available, using Python version AVLTree.

  Warning: FastRBTree not available, using Python version RBTree.

正确的引入方式是:

>>> from bintrees import BinaryTree   #只引入了BinartTree
  >>> from bintrees import *       #三个模块都引入了

- 实例化

看例子:

>>> btree = BinaryTree()
  >>> btree
  BinaryTree({})
  >>> type(btree)
  <class 'bintrees.bintree.BinaryTree'>

  
- 逐个增加键值对: .__setitem__(k,v) .复杂度O(log(n))(后续说明中,都会有复杂度标示,为了简单,直接标明:O(log(n)).)

看例子:

>>> btree.__setitem__("Tom","headmaster")
 >>> btree
 BinaryTree({'Tom': 'headmaster'})
 >>> btree.__setitem__("blog","http://blog.csdn.net/qiwsir")
 >>> btree
 BinaryTree({'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})

  
- 批量添加: .update(E)  E是dict/iterable,将E批量更新入btree. O(E*log(n))

看例子:

>>> adict = [(2,"phone"),(5,"tea"),(9,"scree"),(7,"computer")]
  >>> btree.update(adict)
  >>> btree
  BinaryTree({2: 'phone', 5: 'tea', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})

  
- 查找某个key是否存在: .__contains__(k)  如果含有键k,则返回True,否则返回False. O(log(n))

看例子:

>>> btree
 BinaryTree({2: 'phone', 5: 'tea', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
 >>> btree.__contains__(5)
 True
 >>> btree.__contains__("blog")
 True
 >>> btree.__contains__("qiwsir")
 False
 >>> btree.__contains__(1)
 False

  
- 根据key删除某个key-value: .__delitem__(key), O(log(n))

看例子:

>>> btree
  BinaryTree({2: 'phone', 5: 'tea', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
  >>> btree.__delitem__(5)    #删除key=5的key-value,即:5:'tea' 被删除.
  >>> btree
  BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})

- 根据key值得到该kye的value: .__getitem__(key)

看例子:

>>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
 >>> btree.__getitem__("blog")
 'http://blog.csdn.net/qiwsir'
 >>> btree.__getitem__(7)
 'computer'
 >>> btree._getitem__(5)  #在btree中没有key=5,于是报错。
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 AttributeError: 'BinaryTree' object has no attribute '_getitem__'

- 迭代器: .__iter__()

看例子:

>>> btree 
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
 >>> aiter = btree.__iter__()
 >>> aiter
 <generator object <genexpr> at 0xb7416dec>
 >>> aiter.next() #注意:next()一个之后,该值从list中删除
 2
 >>> aiter.next()
 7
 >>> list(aiter)
 [9, 'Tom', 'blog']
 >>> list(aiter)  #结果是空
 []
 >>> bool(aiter)  #but,is True
 True

- 树的数据长度: .__len__(),返回btree的长度。O(1)

看例子:

>>> btree
  BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'Tom': 'headmaster', 'blog': 'http://blog.csdn.net/qiwsir'})
  >>> btree.__len__()
  5

- 找出key最大的k-v对: .__max__(),按照key排列,返回key最大的键值对。

- 找出key最小的键值对: .__min__()

看例子:

>>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
 >>> btree.__max__()
 (9, 'scree')
 >>> btree.__min__()
 (2, 'phone')

- 两棵树的关系运算

看例子:

>>> other = [(3,'https://3water.com'),(7,'qiwsir')]
 >>> bother = BinaryTree()  #再建一个树
 >>> bother.update(other) #加入数据

 >>> bother
 BinaryTree({3: 'https://3water.com', 7: 'qiwsir'})
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
 
 >>> btree.__and__(bother)  #重叠部分部分
 BinaryTree({7: 'computer'})

 >>> btree.__or__(bother) #全部
 BinaryTree({2: 'phone', 3: 'https://3water.com, 7: 'computer', 9: 'scree'})

 >>> btree.__sub__(bother)  #btree不与bother重叠的部分
 BinaryTree({2: 'phone', 9: 'scree'})
 
 >>> btree.__xor__(bother)  #两者非重叠部分
 BinaryTree({2: 'phone', 3: 'https://3water.com, 9: 'scree'})

- 输出字符串模样,注意仅仅是输出的模样罢了: .__repr__()

看例子:

>>> btree
  BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
  >>> btree.__repr__()
  "BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})"

- 清空树中的所有数据 :.clear(),O(log(n))

看例子:

>>> bother  
 BinaryTree({3: 'http://blog.csdn.net/qiwsir', 7: 'qiwsir'})
 >>> bother.clear()
 >>> bother
 BinaryTree({})
 >>> bool(bother)
 False

- 浅拷贝: .copy(),官方文档上说是浅拷贝,但是我做了操作实现,是下面所示,还不是很理解其“浅”的含义。O(n*log(n))

看例子:

>>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})
 >>> ctree = btree.copy()
 >>> ctree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})

 >>> btree.__setitem__("github","qiwsir") #增加btree的数据
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
 >>> ctree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'}) #这是不是在说明属于深拷贝呢?
 
 >>> ctree.__delitem__(7) #删除ctree的一个数据
 >>> ctree
 BinaryTree({2: 'phone', 9: 'scree'})
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})

  

- 移除树中的一个数据: .discard(key),这个功能与.__delitem__(key)类似.两者都不反悔值。O(log(n))

看例子:

>>> ctree
 BinaryTree({2: 'phone', 9: 'scree'})
 >>> ctree.discard(2) #删除后,不返回值,或者返回None
 >>> ctree
 BinaryTree({9: 'scree'})
 >>> ctree.discard(2) #如果删除的key不存在,也返回None
 >>> ctree.discard(3)
 >>> ctree.__delitem__(3) #但是,.__delitem__(key)则不同,如果key不存在,会报错。
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 264, in __delitem__
  self.remove(key)
  File "/usr/local/lib/python2.7/site-packages/bintrees/bintree.py", line 124, in remove
  raise KeyError(str(key))
  KeyError: '3'

- 根据key查找,并返回或返回备用值: .get(key[,d])。如果key在树中存在,则返回value,否则如果有d,则返回d值。O(log(n))

看例子:

>>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
 >>> btree.get(2,"algorithm")
 'phone'
 >>> btree.get("python","algorithm") #没有key='python'的值,返回'algorithm'
 'algorithm'
 >>> btree.get("python") #如果不指定第二个参数,若查不到,则返回None
 >>>

- 判断树是否为空: is_empty().根据树数据的长度,如果数据长度为0,则为空。O(1)

看例子:

>>> ctree
 BinaryTree({9: 'scree'})
 >>> ctree.clear()  #清空数据
 >>> ctree
 BinaryTree({})
 >>> ctree.is_empty()
 True
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
 >>> btree.is_empty()
 False

- 根据key、value循环从树中取值:

>>.items([reverse])--按照(key,value)结构取值;

>>.keys([reverse])--key

>>.values([reverse])--value. O(n)

>>.iter_items(s,e[,reverse]--s,e是key的范围,也就是生成在某个范围内的key的迭代器 O(n)

看例子:

>>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
 >>> for (k,v) in btree.items():
 ... print k,v
 ...
 2 phone
 7 computer
 9 scree
 github qiwsir
 >>> for k in btree.keys():
 ... print k
 ...
 2
 7
 9
 github
 >>> for v in btree.values():
 ... print v
 ...
 phone
 computer
 scree
 qiwsir
 >>> for (k,v) in btree.items(reverse=True): #反序
 ... print k,v
 ...
 github qiwsir
 9 scree
 7 computer
 2 phone

 >>> btree
 BinaryTree({2: 'phone', 5: None, 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
 >>> for (k,v) in btree.iter_items(6,9): #要求迭代6<=key<9的键值对数据
 ... print k,v
 ...
 7 computer
 8 eight
 >>>

      

- 删除数据并返回该值:

>>.pop(key[,d]), 根据key删除树的数据,并返回该value,但是如果没有,并也指定了备选返回的d,则返回d,如果没有d,则报错;

>>.pop_item(),在树中随机选择(key,value)删除,并返回。

看例子:

>>> ctree = btree.copy()
 >>> ctree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})

 >>> ctree.pop(2) #删除key=2的数据,返回其value
 'phone'
 >>> ctree.pop(2) #删除一个不存在的key,报错
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 350, in pop
  value = self.get_value(key)
  File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 557, in get_value
  raise KeyError(str(key))
  KeyError: '2'
 
 >>> ctree.pop_item()  #随机返回一个(key,value),并已删除之
 (7, 'computer')
 >>> ctree
 BinaryTree({9: 'scree', 'github': 'qiwsir'})
 
 >>> ctree.pop(7,"sing") #如果没有,可以返回指定值
 'sing'

- 查找数据,并返回value: .set_default(key[,d]),在树的数据中查找key,如果存在,则返回该value。如果不存在,当指定了d,则将该(key,d)添加到树内;当不指定d的时候,添加(key,None). O(log(n))

看例子:

>>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree', 'github': 'qiwsir'})
 >>> btree.set_default(7) #存在则返回
 'computer'
 
 >>> btree.set_default(8,"eight") #不存在,则返回后备指定值,并加入到树
 'eight'
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
 
 >>> btree.set_default(5) #如果不指定值,则会加入None
 >>> btree
 BinaryTree({2: 'phone', 5: None, 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})

 >>> btree.get(2) #注意,.get(key)与.set_default(key[,d])的区别
 'phone'
 >>> btree.get(3,"mobile")  #不存在的 key,返回但不增加到树
 'mobile'
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})

- 根据key删除值

>>.remove(key),删除(key,value)

>>.remove_items(keys),keys是一个key组成的list,逐个删除树中的对应数据

看例子:

>>> ctree
 BinaryTree({2: 'phone', 5: None, 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
 >>> ctree.remove_items([5,6])  #key=6,不存在,报错
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/bintrees/abctree.py", line 271, in remove_items
  self.remove(key)
  File "/usr/local/lib/python2.7/site-packages/bintrees/bintree.py", line 124, in remove
  raise KeyError(str(key))
  KeyError: '6'
 
 >>> ctree
 BinaryTree({2: 'phone', 7: 'computer', 8: 'eight', 9: 'scree', 'github': 'qiwsir'})
 >>> ctree.remove_items([2,7,'github']) #按照 列表中顺序逐个删除
 >>> ctree
 BinaryTree({8: 'eight', 9: 'scree'})

   
##以上只是入门的基本方法啦,还有更多内容,请移不到到文章开头的官方网站

Python 相关文章推荐
用Python实现一个简单的多线程TCP服务器的教程
May 05 Python
python中函数总结之装饰器闭包详解
Jun 12 Python
使用Python的Scrapy框架十分钟爬取美女图
Dec 26 Python
利用 python 对目录下的文件进行过滤删除
Dec 27 Python
python numpy 部分排序 寻找最大的前几个数的方法
Jun 27 Python
Django网络框架之HelloDjango项目创建教程
Jun 06 Python
Python 在OpenCV里实现仿射变换—坐标变换效果
Aug 30 Python
解决Python3.8用pip安装turtle-0.0.2出现错误问题
Feb 11 Python
python ETL工具 pyetl
Jun 07 Python
JAVA及PYTHON质数计算代码对比解析
Jun 10 Python
Python urlopen()参数代码示例解析
Dec 10 Python
Python Pandas pandas.read_sql函数实例用法
Jun 21 Python
深入分析在Python模块顶层运行的代码引起的一个Bug
Jul 04 #Python
python之import机制详解
Jul 03 #Python
Python之eval()函数危险性浅析
Jul 03 #Python
python的绘图工具matplotlib使用实例
Jul 03 #Python
python绘图库Matplotlib的安装
Jul 03 #Python
Python实现全局变量的两个解决方法
Jul 03 #Python
Python实现端口复用实例代码
Jul 03 #Python
You might like
php操作excel文件 基于phpexcel
2010/07/02 PHP
Thinkphp多文件上传实现方法
2014/10/31 PHP
PHP使用缓存即时输出内容(output buffering)的方法
2015/08/03 PHP
Yii2隐藏frontend/web和backend/web的方法
2015/12/12 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
2016/03/03 PHP
PHP类和对象相关系统函数与运算符小结
2016/09/28 PHP
为javascript添加String.Format方法
2020/08/11 Javascript
Javascript技巧之不要用for in语句对数组进行遍历
2010/10/20 Javascript
jquery中加载图片自适应大小主要实现代码
2013/08/23 Javascript
防止登录页面出现在frame中js代码
2014/07/22 Javascript
浅谈javascript事件取消和阻止冒泡
2015/05/26 Javascript
拥有一个属于自己的javascript表单验证插件
2016/03/24 Javascript
js实现延迟加载的几种方法
2017/04/24 Javascript
jQuery实现的form转json经典示例
2017/10/10 jQuery
vue使用v-for实现hover点击效果
2018/09/29 Javascript
JavaScript判断数据类型有几种方法及区别介绍
2020/09/02 Javascript
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
2020/12/02 Vue.js
c++生成dll使用python调用dll的方法
2014/01/20 Python
Python Sleep休眠函数使用简单实例
2015/02/02 Python
python 读取DICOM头文件的实例
2018/05/07 Python
python用户评论标签匹配的解决方法
2018/05/31 Python
使用python脚本自动创建pip.ini配置文件代码实例
2019/09/20 Python
python实现ping命令小程序
2020/12/28 Python
英国PC组件和在线电脑商店:SCAN
2019/04/18 全球购物
学前教育求职自荐信范文
2013/12/25 职场文书
大学生职业生涯规划方案
2014/01/03 职场文书
庆七一活动方案
2014/01/25 职场文书
法定代表人授权委托书范文
2014/09/22 职场文书
群众路线教育实践活动整改落实情况汇报
2014/10/28 职场文书
婚礼领导致辞大全
2015/07/28 职场文书
小学语文新课改心得体会
2016/01/22 职场文书
解决Goland 同一个package中函数互相调用的问题
2021/05/06 Golang
redis 存储对象的方法对比分析
2021/08/02 Redis
关于Oracle12C默认用户名system密码不正确的解决方案
2021/10/16 Oracle
Python echarts实现数据可视化实例详解
2022/03/03 Python
Mysql索引失效 数据库表中有索引还是查询很慢
2022/05/15 MySQL