Python数据结构————二叉查找树的实现
对于二叉查找树的每个节点Node,它的左子树中所有的关键字都小于Node的关键字,而右子树中的所有关键字都大于Node的关键字。
二叉查找树的平均深度是O(log N)。
1.初始化
- class BinarySearchTree(object):
- def __init__(self,key):
- self.key=key
- self.left=None
- self.right=None
2.Find
- def find(self,x):
- if x==self.key:
- return self
- elif x<self.key and self.left:
- return self.left.find(x)
- elif x>self.key and self.right:
- return self.right.find(x)
- else:
- return None
3.FindMin和FindMax
分别返回树中的最小元素与最大元素的位置。FindMin,从根开始并且只要有左儿子就向左进行查找,终止点是最小元素。FindMax则向右进行。
- def findMin(self):
- if self.left:
- return self.left.findMin()
- else:
- return self
- def findMax(self):
- tree=self
- if tree:
- while tree.right:
- tree=tree.right
- return tree
4.Insert
为了将x插入到树Tree中,先用find查找,如果找到x,则什么也不做。否则,将x插入到遍历路径的最后一点。
来自《Problem Solving with Algorithms and Data Structures》的图片:
- def insert(self,x):
- if x<self.key:
- if self.left:
- self.left.insert(x)
- else:
- tree=BinarySearchTree(x)
- self.left=tree
- elif x>self.key:
- if self.right:
- self.right.insert(x)
- else:
- tree=BinarySearchTree(x)
- self.right=tree
5.Delete
删除某节点有3种情况:
5.1 如果节点是一片树叶,那么可以立即被删除。
来自《Problem Solving with Algorithms and Data Structures》的图片:
5.2 如果节点只有一个儿子,则将此节点parent的指针指向此节点的儿子,然后删除。
来自《Problem Solving with Algorithms and Data Structures》的图片:
5.3 如果节点有两个儿子,则将其右子树的最小数据代替此节点的数据,并将其右子树的最小数据(不可能有左儿子,只有一个右儿子)删除。
来自《Problem Solving with Algorithms and Data Structures》的图片:
- def delete(self,x):
- if self.find(x):
- if x<self.key:
- self.left=self.left.delete(x)
- return self
- elif x>self.key:
- self.right=self.right.delete(x)
- return self
- elif self.left and self.right:
- key=self.right.findMin().key
- self.key=key
- self.right=self.right.delete(key)
- return self
- else:
- if self.left:
- return self.left
- else:
- return self.right
- else:
- return self
全部代码
- class BinarySearchTree(object):
- def __init__(self,key):
- self.key=key
- self.left=None
- self.right=None
- def find(self,x):
- if x==self.key:
- return self
- elif x<self.key and self.left:
- return self.left.find(x)
- elif x>self.key and self.right:
- return self.right.find(x)
- else:
- return None
- def findMin(self):
- if self.left:
- return self.left.findMin()
- else:
- return self
- def findMax(self):
- tree=self
- if tree:
- while tree.right:
- tree=tree.right
- return tree
- def insert(self,x):
- if x<self.key:
- if self.left:
- self.left.insert(x)
- else:
- tree=BinarySearchTree(x)
- self.left=tree
- elif x>self.key:
- if self.right:
- self.right.insert(x)
- else:
- tree=BinarySearchTree(x)
- self.right=tree
- def delete(self,x):
- if self.find(x):
- if x<self.key:
- self.left=self.left.delete(x)
- return self
- elif x>self.key:
- self.right=self.right.delete(x)
- return self
- elif self.left and self.right:
- key=self.right.findMin().key
- self.key=key
- self.right=self.right.delete(key)
- return self
- else:
- if self.left:
- return self.left
- else:
- return self.right
- else:
- return self
上述写法的缺点是很难处理空树的情况。
另一种类似于链表的写法
- class TreeNode(object):
- def __init__(self,key,left=None,right=None,parent=None):
- self.key=key
- self.left=left
- self.right=right
- self.parent=parent
- def hasLeftChild(self):
- return self.left
- def hasRightChild(self):
- return self.right
- def isLeftChild(self):
- return self.parent and self.parent.left==self
- def isRightChild(self):
- return self.parent and self.parent.right==self
- class BSTree(object):
- def __init__(self):
- self.root=None
- self.size=0
- def length(self):
- return self.size
- def insert(self,x):
- node=TreeNode(x)
- if not self.root:
- self.root=node
- self.size+=1
- else:
- currentNode=self.root
- while True:
- if x<currentNode.key:
- if currentNode.left:
- currentNode=currentNode.left
- else:
- currentNode.left=node
- node.parent=currentNode
- self.size+=1
- break
- elif x>currentNode.key:
- if currentNode.right:
- currentNode=currentNode.right
- else:
- currentNode.right=node
- node.parent=currentNode
- self.size+=1
- break
- else:
- break
- def find(self,key):
- if self.root:
- res=self._find(key,self.root)
- if res:
- return res
- else:
- return None
- else:
- return None
- def _find(self,key,node):
- if not node:
- return None
- elif node.key==key:
- return node
- elif key<node.key:
- return self._find(key,node.left)
- else:
- return self._find(key,node.right)
- def findMin(self):
- if self.root:
- current=self.root
- while current.left:
- current=current.left
- return current
- else:
- return None
- def _findMin(self,node):
- if node:
- current=node
- while current.left:
- current=current.left
- return current
- def findMax(self):
- if self.root:
- current=self.root
- while current.right:
- current=current.right
- return current
- else:
- return None
- def delete(self,key):
- if self.size>1:
- nodeToRemove=self.find(key)
- if nodeToRemove:
- self.remove(nodeToRemove)
- self.size-=1
- else:
- raise KeyError,'Error, key not in tree'
- elif self.size==1 and self.root.key==key:
- self.root=None
- self.size-=1
- else:
- raise KeyError('Error, key not in tree')
- def remove(self,node):
- if not node.left and not node.right: #node为树叶
- if node==node.parent.left:
- node.parent.left=None
- else:
- node.parent.right=None
- elif node.left and node.right: #有两个儿子
- minNode=self._findMin(node.right)
- node.key=minNode.key
- self.remove(minNode)
- else: #有一个儿子
- if node.hasLeftChild():
- if node.isLeftChild():
- node.left.parent=node.parent
- node.parent.left=node.left
- elif node.isRightChild():
- node.left.parent=node.parent
- node.parent.right=node.left
- else: #node为根
- self.root=node.left
- node.left.parent=None
- node.left=None
- else:
- if node.isLeftChild():
- node.right.parent=node.parent
- node.parent.left=node.right
- elif node.isRightChild():
- node.right.parent=node.parent
- node.parent.right=node.right
- else: #node为根
- self.root=node.right
- node.right.parent=None
- node.right=None
Python数据结构————二叉查找树的实现的更多相关文章
- python数据结构树和二叉树简介
一.树的定义 树形结构是一类重要的非线性结构.树形结构是结点之间有分支,并具有层次关系的结构.它非常类似于自然界中的树.树的递归定义:树(Tree)是n(n≥0)个结点的有限集T,T为空时称为空树,否 ...
- python数据结构与算法
最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...
- python数据结构与算法——链表
具体的数据结构可以参考下面的这两篇博客: python 数据结构之单链表的实现: http://www.cnblogs.com/yupeng/p/3413763.html python 数据结构之双向 ...
- python数据结构之图的实现
python数据结构之图的实现,官方有一篇文章介绍,http://www.python.org/doc/essays/graphs.html 下面简要的介绍下: 比如有这么一张图: A -> B ...
- Python数据结构与算法--List和Dictionaries
Lists 当实现 list 的数据结构的时候Python 的设计者有很多的选择. 每一个选择都有可能影响着 list 操作执行的快慢. 当然他们也试图优化一些不常见的操作. 但是当权衡的时候,它们还 ...
- Python数据结构与算法--算法分析
在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程.算法的效率或复杂度在理论上表示为一个函数.其定义 ...
- Python数据结构与循环语句
# Python数据结构与循环语句: 首先编程是一项技能,类似跑步,期初不必在意细节,能使用起来就行,等学的游刃有余了再回过头来关注细节问题也不迟. 关于买书: 学会python之后,才需要买书 ...
- python数据结构之栈与队列
python数据结构之栈与队列 用list实现堆栈stack 堆栈:后进先出 如何进?用append 如何出?用pop() >>> >>> stack = [3, ...
- python数据结构之树和二叉树(先序遍历、中序遍历和后序遍历)
python数据结构之树和二叉树(先序遍历.中序遍历和后序遍历) 树 树是\(n\)(\(n\ge 0\))个结点的有限集.在任意一棵非空树中,有且只有一个根结点. 二叉树是有限个元素的集合,该集合或 ...
随机推荐
- iOS之duplicate symbols for architecture x86_64错误
在我们写代码过程中可能会经常遇到这样一个错误: <span style="font-size:32px;color:#ff0000;">ld: 4 duplicate ...
- Log4Net(三)之记录日志到数据库
前面两篇短文向大家介绍了如何使用log4net,以及如何将log4net记录到文本文件中.下面本文将向大家介绍如何将log4net记录到数据库中. 经过前面的介绍,我想大家对使用log4net的过程已 ...
- [设计模式]<<设计模式之禅>>关于依赖倒置原则
依赖倒置原则(Dependence Inversion Principle,DIP)这个名字看着有点别扭,“依赖”还“倒置”,这到底是什么意思?依赖倒置原则的原始定义是 High level modu ...
- JAVA基础之理解JNI原理
JNI是JAVA标准平台中的一个重要功能,它弥补了JAVA的与平台无关这一重大优点的不足,在JAVA实现跨平台的同时,也能与其它语言(如C.C++)的动态库进行交互,给其它语言发挥优势的机会. 有了J ...
- Ubuntu声音消失
声音图标是 X 将sound的Mute的勾去掉就有声音了. 参考文献: Ubuntu声音全部消失 使用的工具: Shutter
- Jersey(1.19.1) - Client API, Ease of use and reusing JAX-RS artifacts
Since a resource is represented as a Java type it makes it easy to configure, pass around and inject ...
- JS定位PDF页码。
由于项目中的PDF文章段落标题有些是英文,对其翻译后需要定位到具体的页码. 查询相关资料及进行尝试后发现可以用如下方法可以实现 function gotoPage(page) { ...
- HDOJ2001计算两点间的距离
计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- Mysql增加主键或者更改表的列为主键的sql语句
...
- Unity 5.4大赞:HTC Vive经典The lab渲染器开源
HTC Vive提供了一个不错的免费VR demo,最近1周仔细体验了一番. 仔细看了其安装文件,竟然是Unity 5.4beta版本(通过查log,知道Valve公司用的是最新的5.4.0b11版本 ...