@Scrazy
2017-04-13T08:23:49.000000Z
字数 4998
阅读 1135
python2017-03-22畏惧了好久的二叉树,终于在近两天开搞了。二分法查找已在前几天完成,磨刀霍霍向猪羊,吼吼吼!
首先,建立一棵树(二叉搜索树)。
class Node:def __init__(self, data):self.left = Noneself.right = Noneself.data = data
这样,光秃秃的小树苗就种好了。接着就是茁长生长啦。浇水去喽!
class Node:'''...'''def insert(self, data):if data < self.data: # 树叉小于节点if self.left is None: # 并且左面的树叉为空self.left = Node(data) # 当仁不让的插入else: # 非空的话self.left.insert(data) # 以左树叉为节点继续插入elif data > self.data:if self.right is None:self.right = Node(data)else:self.right.insert(data)else:self.data = data
浇完水后,小树苗噌噌的往上窜啊。
class Node:'''省略上述代码'''def search(self, data, parent=None):'''data为目标查询值,同时返回parent(父节点)便于定位。'''if data < self.data:if self.left is None:return None, Noneelse:return self.left.search(data, self)elif data > self.data:if self.right is None:return None, Nonereturn self.right.search(data, self)else:# return self.data, parent.datareturn self, parent
树苗生长的那么好,想看看每个叉上都是啥呀,来来来,抬头往上看((其实是往下看啦)。
def print_tree(self):if self.left:self.left.print_tree()print(self.data, end=' ')if self.right:self.right.print_tree()
树的遍历又分为以下三种:
调整print_tree函数里 print(self.data, end=' ') 的顺序即可实现三种遍历方式。
转眼间小树苗涨的太旺盛了,疯涨啊!!怎么办呢,剪几个枝吧。别怪我哦,小树苗! 删除节点时,有三种可能的情况:
判断节点数目程序如下:
class Node:'''省略代码'''def chrildren(self):count = 0if self.left:count += 1if self.right:count += 1return count
接下来就是删除操作啦。哦吼吼。
class Node:'''省略'''def delete(self, data):node, parent = self.search(data)chrildren = node.chrildren() # 子节点数目if chrildren == 0: # 情况 1, 没有子节点,直接删除即可if parent.left is node: # 判断目标节点是其父节点的 左or右 节点parent.left = Noneelse:parent.right = Nonedel nodeelif chrildren == 1: # 情况 2, 有一个子节点,用子节点替换其即可if node.left:tmp = node.leftelse:tmp = node.rightif parent:if parent.left is node:parent.left = tmpelse:parent.right = tmpdel nodeelse:'''第三种情况比较复杂:1\. 左节点0个子节点2\. 左节点1个子节点3\. 左节点2个子节点'''parent = nodesuccessor = node.rightwhile successor.left: # 递归思想,直至找到'最左'的子节点, 保持树的平衡,用右子节点的值替换parent = successorsuccessor = successor.leftnode.data = successor.dataif parent.left == successor:parent.left = successor.rightelse:parent.right = successor.right# 接下来可以测试以下种的树怎么样啦。root = Node(11) root.insert(14) root.insert(9) root.insert(9) root.insert(7) root.insert(10) root.insert(4) root.insert(5) root.inser)
把自己理解的部分写了写。当做练习,就先当个α版吧。
2016-05-28
基本搞明白了
完整代码在这里
def lookup(root):stack = [root]while stack:current = stack.pop()print(current.data, end=' ')if current.left:stack.append(current.left)if current.right:stack.append(current.right)def deep(root):if not root:returndeep(root.left)deep(root.right)print(root.data, end=' ')
# -*- coding:utf-8 -*-class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = Noneclass Solution:def TreeDepth(self, pRoot):if not pRoot:return 0return max(self.TreeDepth(pRoot.left), self.TreeDepth(pRoot.right)) + 1
def is_same(t1, t2):if t1 == None and t2 == None:return Trueelif t1 and t2:return t1.data == t2.data and is_same(t1.left, t2.left)\and is_same(t1.right, t2.right)else:return False
前面说到:
前序: root -> left -> right
中序: left -> root -> right
后序: left -> right -> root
前序: 第一个值 A 即为根节点
中序: A 的左边全为左子树,右边全是右子树
def pre_in_post(pre_order, in_order):if not pre_order:returnpost = Node(pre_order[0])index = in_order.index(pre_order[0])post.left = pre_in_post(pre_order[1:index+1], in_order[:index])post.right = pre_in_post(pre_order[index+1:], in_order[index+1:])return post
# -*- coding:utf-8 -*-class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = Noneclass Solution:# 返回构造的TreeNode根节点def reConstructBinaryTree(self, pre, tin):# write code hereif not pre:returntree = TreeNode(pre[0])index = tin.index(pre[0])tree.left = self.reConstructBinaryTree(pre[1:index+1],tin[:index])tree.right = self.reConstructBinaryTree(pre[index+1:],tin[index+1:])return tree@classmethoddef print_tree(cls, tree):if tree:cls.print_tree(tree.left)cls.print_tree(tree.right)print(tree.val)pre = [1,2,3,4,5,6,7]tin = [3,2,4,1,6,5,7]s = Solution()t = s.reConstructBinaryTree(pre, tin)s.print_tree(t)
求pRoot2 的子树是否为 pRoot2# -*- coding:utf-8 -*-# class TreeNode:# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution:def is_subtree(self, t1, t2):if not t2: # t2 is None 其为子树return Trueif not t1:return Falseif not t1.val == t2.val:return Falsereturn self.is_subtree(t1.left, t2.left) and self.is_subtree(t1.right, t2.right)def HasSubtree(self, pRoot1, pRoot2):# write code hereresult = Falseif pRoot1 and pRoot2:if pRoot1.val == pRoot2.val:result = self.is_subtree(pRoot1, pRoot2)if not result:result = self.is_subtree(pRoot1.left, pRoot2)if not result:result = self.is_subtree(pRoot1.right, pRoot2)return result
# -*- coding:utf-8 -*-# class TreeNode:# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution:def isSymmetrical(self, pRoot):def is_same(p1, p2):if not (p1 or p2):return Trueelif p1 and p2 and p1.val == p2.val:return is_same(p1.left, p2.right) and is_same(p1.right, p2.left)return Falseif not pRoot:return Truereturn is_same(pRoot.left, pRoot.right)
# -*- coding:utf-8 -*-# class TreeNode:# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution:# 返回镜像树的根节点def Mirror(self, root):if not root:return Noneelif not (root.left or root.right):return rootroot.left, root.right = root.right, root.leftif root.left:self.Mirror(root.left)if root.right:self.Mirror(root.right)