二叉树复习 & 重建二叉树 & 树的子结构 & 二叉树的镜像 & 从上往下打印二叉树 & 二叉树中和为某一值的路径 & 二叉树搜索与双向链表 & 二叉树的下一个节点 & 对称的二叉树 &之形印二叉树

二叉树复习

各种遍历后结果
pre:12453687
mid:42516837
last:45286731
class TreeNode:

    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None


def pre_recursion_order(root):
    """递归方式 执行遍历"""
    if root == None:
        return None
    print(root.val)  # 先序遍历
    pre_recursion_order(root.left)
    # print(root.val)  # 中序遍历
    pre_recursion_order(root.right)
    # print(root.val)  # 先序遍历


def pre_iteration_order(root):
    """迭代方式 执行遍历"""
    if root == None:
        return None
    tempNode = root
    stack = []
    while stack or tempNode:
        while tempNode:
            # print(tempNode.val)  # 先序打印
            stack.append(tempNode)
            tempNode = tempNode.left

        node = stack.pop()
        print(node.val)  # 中序遍历
        tempNode = node.right


def last_iteration_order(root):
    """后续稍微麻烦,左,右,根"""
    if root == None:
        return None
    tempNode = root
    stack = []
    while stack or tempNode:
        while tempNode:
            stack.append(tempNode)
            tempNode = tempNode.left
        node = stack[-1]  # 第一次这里node=4, stack=[1, 2, 4]
        tempNode = node.right
        if node.right == None:
            node = stack.pop()
            print(node.val)  # 
            while stack and node == stack[-1].right:  # 
                node = stack.pop()  
                print(node.val)  #


if __name__ == "__main__":
    t1 = TreeNode(1)
    t2 = TreeNode(2)
    t3 = TreeNode(3)
    t4 = TreeNode(4)
    t5 = TreeNode(5)
    t6 = TreeNode(6)
    t7 = TreeNode(7)
    t8 = TreeNode(8)

    t1.left = t2
    t1.right = t3
    t2.left = t4
    t2.right = t5
    t3.left = t6
    t3.right = t7
    t6.right = t8

    pre_recursion_order(t1)
    print('---' * 10)
    pre_iteration_order(t1)
    print('---' * 10)
    last_iteration_order(t1)

重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if pre == []:
            return None
        root = TreeNode(pre[0])
        pos = tin.index(pre[0])
        root.left = self.reConstructBinaryTree(pre[1:pos+1], tin[:pos])
        root.right = self.reConstructBinaryTree(pre[pos+1:], tin[pos+1:])
        return root

树的子结构:

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        if pRoot1 == None or pRoot2 == None:
            return False
        return self.judge_sub_tree(pRoot1, pRoot2) 
    
    def judge_sub_tree(self, root1, root2):
        if root2 == None:
            return True
        if root1 == None:
            return root1 == root2
        res = False
        if root1.val == root2.val:  # 看这个子结构是不是在左节点侧,或者在右节点侧
            res =  self.judge_sub_tree(root1.left, root2.left) and self.judge_sub_tree(root1.right, root2.right)

        return res or self.judge_sub_tree(root1.left, root2) or self.judge_sub_tree(root1.right, root2)

二叉树的镜像:

操作给定的二叉树,将其变换为源二叉树的镜像
二叉树的镜像定义:源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if root == None:
            return None
        
        root.left, root.right = root.right, root.left
        
        self.Mirror(root.left)
        self.Mirror(root.right)
        
        return root

从上往下打印二叉树 (别和前序、中序、后续、遍历搞混了!)

# 从上往下打印出二叉树的每个节点,同层节点从左至右打印

class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        # write code here
        if root == None:
            return []
        
        res = []
        temp = [root]
        
        while temp:
            node = temp.pop(0)
            res.append(node.val)
            
            if node.left:
                temp.append(node.left)
            if node.right:
                temp.append(node.right)
        return res

二叉搜索树的后续遍历序列

题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

二叉搜索树复习:

# 这题的验证程序确实傻逼,即使收入为[]它也是一个搜索二叉树啊

class Solution:
    def VerifySquenceOfBST(self, sequence):
        # write code here
        # 主要思路是:后续遍历,左右根,最后一个是根节点
        # 那么前面的 [1, 4, 2, 6, 11, 9, 5], 那么这里5是根节点
        # 那么 143 为左子树, 6 11 9 为右子树,
        # 那么 如果遍历过程中,找到第一个数的index,它大于根节点,那么就分出了左右子树
        # 如果 6 后面还出现了小于于5的树,那就判定为false 比如 [1, 4, 2, 6, 2, 9, 5]
        if sequence == []:
            return False
        root = sequence[-1]
        sequence.pop()
        index = None
        for i in range(len(sequence)):
            if not index and sequence[i] > root:
                index = i # 比如找到 6 的位置,index = 3
            if index != None and sequence[i] < root: # 继续往下遍历,看有没有其他数小于5
                return False
            
        if sequence[:index] == []:
            return True
        else:
            left_res = self.VerifySquenceOfBST(sequence[:index])
        if sequence[index:] == []:
            return True
        else:
            right_res = self.VerifySquenceOfBST(sequence[index:])
        
        return left_res and right_res

二叉树中和为某一路径的值

输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

# 复习 浅拷贝 & 深拷贝
>>> import copy
>>> origin = [1, 2, [3, 4]]
#origin 里边有三个元素:1, 2,[3, 4]
>>> cop1 = copy.copy(origin)
>>> cop2 = copy.deepcopy(origin)
>>> cop1 == cop2
True
>>> cop1 is cop2
False 
#cop1 和 cop2 看上去相同,但已不再是同一个object
>>> origin[2][0] = "hey!" 
>>> origin
[1, 2, ['hey!', 4]]
>>> cop1
[1, 2, ['hey!', 4]]
>>> cop2
[1, 2, [3, 4]]
#把origin内的子list [3, 4] 改掉了一个元素,观察 cop1 和 cop2
举一个例子,这里和为23,有两条路径[[5, 9, 6, 3], [5, 2, 1]]
             5
    	   /  \
    	  2    9
    	 / \  / \
    	1  16 6  11
             /
            3
import copy
class Solution:
    # 返回二维列表,内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        # write code here
        if root == None:
            return []
        
        res = []
        Array_list = [[root.val]]   # 这个临时存储list路径是真的牛皮,服了!
        temp = [root]
        
        while temp:
            node = temp.pop(0)
            temp_list = Array_list.pop(0)
            if node.left == None and node.right == None:
                if sum(temp_list) == expectNumber:
                    res.insert(0, temp_list)
                    
            if node.left:
                temp.append(node.left)
                new_temp_list = copy.copy(temp_list)  # # 这里的浅拷贝也非常好
                new_temp_list.append(node.left.val)
                Array_list.append(new_temp_list)
            if node.right:
                temp.append(node.right)
                new_temp_list = copy.copy(temp_list)
                new_temp_list.append(node.right.val)
                Array_list.append(new_temp_list)
        return res

二叉树搜索与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

思路:
举例
             5
    	   /  \
    	  2    9
    	 / \  / \
    	1  16 6  11

1)看图说话,你看因为是搜索二叉树,看两个子树比如 
    左子树 1<-2->16 
    右子树 6<-9->11
    父节点   2<-5->9   (这里因为要构成双向链表明显不对,应该是16<-5->5)
2) 注意看,刚才的左右子树,只需要各个子节点比如 left=1 连向mid=2, right=16 连向 mid=2
3)但是顶部的父节点,明显是连接的左子树的 最右节点16,   右子树的最左节点6   才能构成双向链表

参考链接:https://blog.csdn.net/u010005281/article/details/79657259

# 二叉树中序遍历的方法
# 最基本的中序遍历复习一波
class Solution:
    def __init__(self):
        self.array = []

    def mid_traval(self, root):
        if not root:
            return self.array
        self.mid_traval(root.left)
        self.array.append(root.val)
        print(root.val)
        self.mid_traval(root.right)


# 看看改进版,我都不知道他们怎么想到的
class Solution:
        # write code here
    def __init__(self):
        self.listHead = None
        self.listTail = None

    def Convert(self, pRootOfTree):
        if pRootOfTree == None:
            return
        self.Convert(pRootOfTree.left)
        if self.listHead == None:
            self.listHead = pRootOfTree
            self.listTail = pRootOfTree
        else:
            self.listTail.right = pRootOfTree
            pRootOfTree.left = self.listTail
            self.listTail = pRootOfTree
        self.Convert(pRootOfTree.right)
        return self.listHead


# 来个正常人思路版本

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
        # write code here
    def Convert(self, pRootOfTree):
        
        if pRootOfTree == None:
            return None
        
        left = self.Convert(pRootOfTree.left)
        right = self.Convert(pRootOfTree.right)
        
        start = left
        
        # 这里如果是 左子树,找到它的最右的子节点,一会要连接中间节点
        # 注意叶子节点的最右节点,最左节点是它本身
        if left:
            left = self.find_rightest(left)
            left.right = pRootOfTree
        else:
            start = pRootOfTree # 这里解释,最后的叶子节点,后面的None也会进入递归,这里吧start给那个叶子节点,而不是None
        
        pRootOfTree.left = left
        pRootOfTree.right = right
        
        if right:
            right.left = pRootOfTree
        return start

    def find_rightest(self, node):
        while node.right:
            node = node.right
        return node
        return begin

if __name__ == "__main__":
    t1 = TreeNode(4)
    t2 = TreeNode(2)
    t3 = TreeNode(6)
    t4 = TreeNode(1)
    t5 = TreeNode(3)
    t6 = TreeNode(5)
    t7 = TreeNode(7)

    t1.left = t2
    t1.right = t3
    t2.left = t4
    t2.right = t5
    t3.left = t6
    t3.right = t7

    B = Solution2()
    aa = B.Convert(t1)
    a = 1

二叉树的下一个节点:

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code here
        
        # 找规律的感觉,如果存在右子树,则找到右子树的最左节点,就是中序遍历的下一个节点
        if pNode.right:
            temp_node = pNode.right
            while temp_node.left:
                temp_node = temp_node.left
            return temp_node
        # 如果没有最右子树,那么就看这个节点A的父节点B,A是不是B的左节点,是就输出,否则继续再中序
        # 遍历中继续下一个节点,这就是为什么题目说了有next这个东西
        else:
            temp_node = pNode
            while temp_node.next:
                if temp_node.next.left == temp_node:
                    return temp_node.next
                temp_node = temp_node.next
            return None

对称的二叉树:

请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        # write code here
        # 主要思路2步: 1) 判断两个节点值是否相等,2)判断A节点的左节点值 == B节点的右节点值
        # 边界条件, 头结点为空的时候,也算对称为True
        if pRoot == None:
            return True
        
        return self.judge_node(pRoot.left, pRoot.right)
        
        
    def judge_node(self, left, right):
        
        # 递归的出口,最后的节点情况,注意这里是 left, right
        if left == None and right == None:
            return True
        elif left == None or right == None:
            return False
        
        if left.val != right.val:  # 判断A,B 节点
            return False
        
        res1 = self.judge_node(left.left, right.right) # 判断A,B下面子节点
        res2 = self.judge_node(left.right, right.left)
        
        return res1 and res2

按之字形顺序打印二叉树:

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Print(self, pRoot):
        # write code here
        # 需要用两个stack来保存不同的顺序,需要res来保存结果
        # 注意append的顺序哦,stack1中节点的子节点保存到 stack2,append  left ,right
        # stack2中节点的子节点保存到 stack1 时候,是先append right,left 调试一下就知道了
        # 二叉树如果长这样
        #     1
    	#   /  \
    	#  2    3
    	# / \  / \
    	#4   5 6  7
        # 那么 res 的变化是 [[1], [3, 2], [4, 5, 6, 7]]
        
        if pRoot == None:
            return []
        
        res = []
        stack1 = [pRoot]
        stack2 = []
        
        while stack1 or stack2:
            if stack1:
                temp_res = [] # 保存这行顺序的结果
                while stack1:
                    temp_node = stack1.pop()
                    temp_res.append(temp_node.val)
                    if temp_node.left:  # 注意不要把 None append 进去
                        stack2.append(temp_node.left)  # 先append left
                    if temp_node.right:
                        stack2.append(temp_node.right) # 后append right
                res.append(temp_res)
            
            if stack2:
                temp_res = []
                while stack2:
                    temp_node = stack2.pop()
                    temp_res.append(temp_node.val)
                    if temp_node.right:
                        stack1.append(temp_node.right)  # 先 right
                    if temp_node.left:
                        stack1.append(temp_node.left)   # 后 left
                res.append(temp_res)
                
        return res

把二叉树打印成多行

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if pRoot == None:
            return []
        
        res = []
        stack1 = [pRoot]
        stack2 = []
        
        while stack1 or stack2:
            if stack1:
                temp_res = [] # 保存这行顺序的结果
                while stack1:
                    temp_node = stack1.pop(0)
                    temp_res.append(temp_node.val)
                    if temp_node.left:  # 注意不要把 None append 进去
                        stack2.append(temp_node.left)  # 先append left
                    if temp_node.right:
                        stack2.append(temp_node.right) # 后append right
                res.append(temp_res)
            
            if stack2:
                temp_res = []
                while stack2:
                    temp_node = stack2.pop(0)
                    temp_res.append(temp_node.val)
                    if temp_node.left:
                        stack1.append(temp_node.left)  
                    if temp_node.right:
                        stack1.append(temp_node.right)  
                res.append(temp_res)
                
        return res

二叉搜索树第K小的节点

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回对应节点TreeNode
    def KthNode(self, pRoot, k):
        # write code here
        # 注意 二叉搜索树的 中序遍历 就是有序数列
        if pRoot == None:
            return None
        res = []
        
        def mid_order(node):
            if node == None:
                return None
            mid_order(node.left)
            res.append(node)
            mid_order(node.right)
        
        mid_order(pRoot)
        if k < 1 or k > len(res):
            return None
        
        return res[k-1]

序列化二叉树:

请实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Serialize(self, root):
        res = []
        def pre_order(root):
            if root == None:
                res.append("#")
                return 
            res.append(str(root.val))
            pre_order(root.left)
            pre_order(root.right)
        pre_order(root)
        return " ".join(res)
        # write code here
    def Deserialize(self, s):
        # write code here
        res = s.split()
        def depre_order():
            if res == []:
                return None
            rootVal = res.pop(0)
            if rootVal == "#":
                return None
            node = TreeNode(int(rootVal))
            leftnode = depre_order()
            rightnode = depre_order()
            
            node.left = leftnode
            node.right = rightnode
            return node
        
        pRoot = depre_order()
        return pRoot

二叉树的深度:

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def TreeDepth(self, pRoot):
        # write code here
        # 方法一:递归,注意返回值是return 0
        #if pRoot == None:
            #return 0
        #left = self.TreeDepth(pRoot.left)
        #right = self.TreeDepth(pRoot.right)
        #return max(left, right) + 1
        
        # 方法二:利用数据结构queue,pop(0)
        if pRoot == None:
            return 0
        temp = [pRoot]
        d, count = 0, 0
        next_count = len(temp)
        while len(temp) != 0:
            node = temp.pop(0)
            count += 1
            if node.left:
                temp.append(node.left)
            if node.right:
                temp.append(node.right)
            if count == next_count:
                d += 1
                count = 0
                next_count = len(temp)
        return d

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值