国庆七天乐,回家呆了几天,走亲访友,看到老人们身体健康,精神头也足,自己也挺开心的。在家睡觉也很舒服,每天可以过得很开心,有的时候真觉得小城市的生活节奏好像也不错。不过时间过得是真的快,很多事也必须要赶紧解决才行。
过完国庆回来又重拾数据结构,回顾二叉搜索树的相关内容时不免感觉到有些陌生,所以慢慢来。
二叉搜索树主要的几个操作分别是:搜索、插入、删除、查找最值。
首先还是搞一下二叉搜索树的基本概念,简单来说就是右儿子最大,父亲中等,左儿子最小。
先建立二叉树类:
class tr(object):
def __init__(self,data=None):
self.right = None
self.left = None
self.data = data
然后是第一个功能,查找。
查找的思路相对简单:给定一个树的根节点,再给出一个待查找的值tar。如果tar比当前节点的值大就从当前节点的右子树中继续查找,如果小就从当前节点的左子树中继续查找,如果等于就返回当前节点。如果最终查不到,就代表树中没有这个值,返回一个None。下面是find的代码:
def find(tar,root):
if not root:
return None
if tar > root.data:
return find(tar,root.right)
if tar < root.data:
return find(tar,root.left)
if tar == root.data:
return root
然后是插入操作。插入操作的功能:给出一个树的根节点和待插入的值tar,为tar找到合适的位置插入,然后返回整棵树的根节点。如何确定合适的位置呢?那肯定是按照左<根<右的原则。而且,如果能在树中找到tar,就表示这个值插不进去,那就直接返回根节点。源代码如下:
def insert(root,tar):
#代表已经到了最后一层
if not root:
return tr(tar)
if tar > root.data:
root.right = insert(root.right,tar)
if tar < root.data:
root.left = insert(root.left,tar)
return root
由这个插入操作,可以想到一个建树的函数,输入一个ArrayList,然后把树建好,然后返回建好的树的根节点,python代码如下:
def build(lis):
ro = tr(lis[0]) #ro代表树根
for x in lis[1:]:
insert(ro,x)
return ro
最后一个操作就是删除了,删除这个操作也算是BST操作中比较复杂的一个。删除要求给出一个树的根节点和待删除的值,然后返回删除完成后的树的根节点。函数的基本模式也是使用递归,所以问题就出在待删除节点的情况上。待删节点要是个叶节点,那好说,直接删了就完事了,不会连锁反应。要是待删节点有两个子树的话那就复杂了,采取的办法是:找到该节点右子树中的最小值,把当前节点的值改成这个最小值,然后再在当前节点的右子树中删除这个最小值。如果待删节点只有一个儿子,那也好办,把这个儿子接到现在这个节点的位置就行。python代码如下:
def delete(root,tar):
tmp = tr()
if not root:
return None
if tar > root.data:
root.right = delete(root.right,tar)
if tar < root.data:
root.left = delete(root.left,tar)
else:
if root.right and root.left:
tmp = find_min(root.right)
root.data = tmp.data
root.right = delete(root.right,root.data)
else:
if not root.left:
root = root.right
elif not root.right:
root = root.left
return root
这其中用到了一个find_min函数,也就是查找最小值,这个函数思路还是蛮简单:最小的都在左边,直接往左走到底,那就是最小值了。源码如下:
def find_min(root):
k = root
while k.left:
k = k.left
return k
以上就是BST的基本操作,不算是特别难,但也得掌握扎实,这样做起题来就更舒服一些。