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

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,'http://www.jb51.net'),(7,'qiwsir')]
 >>> bother = BinaryTree()  #再建一个树
 >>> bother.update(other) #加入数据

 >>> bother
 BinaryTree({3: 'http://www.jb51.net', 7: 'qiwsir'})
 >>> btree
 BinaryTree({2: 'phone', 7: 'computer', 9: 'scree'})

 >>> btree.__and__(bother)  #重叠部分部分
 BinaryTree({7: 'computer'})

 >>> btree.__or__(bother) #全部
 BinaryTree({2: 'phone', 3: 'http://www.jb51.net, 7: 'computer', 9: 'scree'})

 >>> btree.__sub__(bother)  #btree不与bother重叠的部分
 BinaryTree({2: 'phone', 9: 'scree'})

 >>> btree.__xor__(bother)  #两者非重叠部分
 BinaryTree({2: 'phone', 3: 'http://www.jb51.net, 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'})

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

时间: 2014-07-03

python数据结构之二叉树的统计与转换实例

一.获取二叉树的深度 就是二叉树最后的层次,如下图: 实现代码: 复制代码 代码如下: def getheight(self):        ''' 获取二叉树深度 '''        return self.__get_tree_height(self.root) def __get_tree_height(self, root):        if root is 0:            return 0        if root.left is 0 and root.righ

python数据结构之二叉树的遍历实例

遍历方案   从二叉树的递归定义可知,一棵非空的二叉树由根结点及左.右子树这三个基本部分组成.因此,在任一给定结点上,可以按某种次序执行三个操作:   1).访问结点本身(N)   2).遍历该结点的左子树(L)   3).遍历该结点的右子树(R) 有次序:   NLR.LNR.LRN 遍历的命名 根据访问结点操作发生位置命名:NLR:前序遍历(PreorderTraversal亦称(先序遍历))  --访问结点的操作发生在遍历其左右子树之前.LNR:中序遍历(InorderTraversal)

Python算法之求n个节点不同二叉树个数

问题 创建一个二叉树 二叉树有限多个节点的集合,这个集合可能是: 空集 由一个根节点,和两棵互不相交的,分别称作左子树和右子树的二叉树组成 创建二叉树: 创建节点 再创建节点之间的关系 Python代码示例 # !/usr/bin/env python # -*-encoding: utf-8-*- # author:LiYanwei # version:0.1 class TreeNode(object): def __init__ (self, data, left = None, righ

python数据结构之二叉树的建立实例

先建立二叉树节点,有一个data数据域,left,right 两个指针域 复制代码 代码如下: # -*- coding: utf - 8 - *- class TreeNode(object): def __init__(self, left=0, right=0, data=0):        self.left = left        self.right = right        self.data = data 复制代码 代码如下: class BTree(object):

Python利用前序和中序遍历结果重建二叉树的方法

本文实例讲述了Python利用前序和中序遍历结果重建二叉树的方法.分享给大家供大家参考,具体如下: 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 这道题比较容易,前序遍历的结果中,第一个结点一定是根结点,然后在中序遍历的结果中查找这个根结点,根结点左边的就是左子树,根结点右边的就是右子树,递归构造出左.右子树即可.示意图如图所示: 利用前序和中序遍历的结果重建二叉树 Python代码: # coding: utf-8 ''

C++基于先序、中序遍历结果重建二叉树的方法

本文实例讲述了C++基于先序.中序遍历结果重建二叉树的方法.分享给大家供大家参考,具体如下: 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 实现代码: #include <iostream> #include <vector> #include <stack> using

通过先序遍历和中序遍历后的序列还原二叉树(实现方法)

当我们有一个 先序遍历序列:1,3,7,9,5,11 中序遍历序列:9,7,3,1,5,11 我们可以很轻松的用笔写出对应的二叉树.但是用代码又该如何实现? 下面我们来简单谈谈基本思想. 首先,先序遍历的顺序是根据 根-左孩子-右孩子 的顺序遍历的,那么我们可以率先确认的是先序遍历序列的第一个数就是根节点,然后中序遍历是根据 左孩子-根-右孩子 的顺序遍历的.我们通过先序遍历确认了根节点,那么我们只需要在中序遍历中找到根节点的位置,然后就可以很好地区分出,那些属于左子树的节点,那些是属于右子树的

Python实现二叉树前序、中序、后序及层次遍历示例代码

前言 树是数据结构中非常重要的一种,主要的用途是用来提高查找效率,对于要重复查找的情况效果更佳,如二叉排序树.FP-树.另外可以用来提高编码效率,如哈弗曼树. 用 Python 实现树的构造和几种遍历算法.实现功能如下: 树的构造 递归实现先序遍历.中序遍历.后序遍历 堆栈实现先序遍历.中序遍历.后序遍历 队列实现层次遍历 # -*- coding=utf-8 -*- class Node(object): """节点类""" def __ini

Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】

本文实例讲述了Python二叉树的遍历操作.分享给大家供大家参考,具体如下: # coding:utf-8 """ @ encoding: utf-8 @ author: lixiang @ email: lixiang_cn@foxmail.com @ python_version: 2 @ time: 2018/4/11 0:09 @ more_info: 二叉树是有限个元素的集合,该集合或者为空.或者有一个称为根节点(root)的元素及两个互不相交的.分别被称为左子树和

PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解

本文实例讲述了PHP实现二叉树深度优先遍历(前序.中序.后序)和广度优先遍历(层次).分享给大家供大家参考,具体如下: 前言: 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历.中序遍历.后序遍历.具体说明如下: 前序遍历:根节点->左子树->右子树 中序遍历:左子树->根节点->右子树 后序遍历:左子树->右子树->根节点 广度优先遍历:又叫层次遍历,从上往下对每一层依

Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例

本文实例讲述了Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作.分享给大家供大家参考,具体如下: 实现一个功能: 输入:一颗二叉树的先序和中序遍历     输出:后续遍历 思想: 先序遍历中,第一个元素是树根     在中序遍历中找到树根,左边的是左子树 右边的是右子树 Python代码: # -*- coding:utf-8 -*- def fromFMtoL( mid ): global las #全局后序遍历 global fir #先序遍历 root = fir[0] #取

C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法

本文实例讲述了C#使用前序遍历.中序遍历和后序遍历打印二叉树的方法.分享给大家供大家参考.具体实现方法如下: public class BinaryTreeNode { public BinaryTreeNode Left { get; set; } public BinaryTreeNode Right { get; set; } public int Data { get; set; } public BinaryTreeNode(int data) { this.Data = data;

PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法

本文实例讲述了PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法.分享给大家供大家参考,具体如下: 先来看看前序遍历.中序遍历与后序遍历原理图: 根据树的前序遍历和中序遍历构造树并输出后序遍历代码如下: <?php class BinaryTreeNode{ public $m_value; public $m_left; public $m_right; } function ConstructCore($preorder,$inorder){ if(count($preorder)!

Java二叉搜索树遍历操作详解【前序、中序、后序、层次、广度优先遍历】

本文实例讲述了Java二叉搜索树遍历操作.分享给大家供大家参考,具体如下: 前言:在上一节Java二叉搜索树基础中,我们对树及其相关知识做了了解,对二叉搜索树做了基本的实现,下面我们继续完善我们的二叉搜索树. 对于二叉树,有深度遍历和广度遍历,深度遍历有前序.中序以及后序三种遍历方法,广度遍历即我们寻常所说的层次遍历,如图: 因为树的定义本身就是递归定义,所以对于前序.中序以及后序这三种遍历我们使用递归的方法实现,而对于广度优先遍历需要选择其他数据结构实现,本例中我们使用队列来实现广度优先遍历.