二叉树算法整理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_36372879/article/details/85918490

算法1, 序列化二叉树(二叉树的先序遍历)

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def __init__(self):
        self.index = 0
        self.listS = []
    def RecursionSe(self, root):
        series = ''
        if root == None:
            series += ',$'
        else:
            series += (',' + str(root.val))
            series += self.RecursionSe(root.left)
            series += self.RecursionSe(root.right)
        return series
    def Serialize(self, root):
        # write code here
        return self.RecursionSe(root)[1:]

测试:

root = TreeNode(11)
root.left = TreeNode(2)
root.right = TreeNode(3)
series = Solution().Serialize(root)

输出:
在这里插入图片描述


算法2,反序列化二叉树

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def __init__(self):
        self.index = 0
        self.listS = []
    def RecursionDe(self):
        node = None
        if self.index < len(self.listS):
            if self.listS[self.index] == '$':
                self.index += 1   #将节点为空之后就直接返回了
            else:
                node = TreeNode(int(self.listS[self.index]))
                self.index += 1
                node.left = self.RecursionDe()
                node.right = self.RecursionDe()
        return node
    def Deserialize(self, s):
        # write code here
        self.listS = s.split(',')   #将序列化的字符串变为数组
        return self.RecursionDe()

测试:

root = Solution().Deserialize(series)
print(root.val)
print(root.left.val)
print(root.right.val)
print(root.right.right)

在这里插入图片描述


算法3,层次化遍历二叉树

使用一个队列层次遍历

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        # write code here
        list = []
        result = []  #注意两个列表如果相等赋值,那么一下就会更新两个
        ####  list = result = []   !!!!错误
        if root == None:
            return list
        list.append(root)
        while list != []:
            treeNode = list.pop(0)
            result.append(treeNode.val)
            if treeNode.left:
                list.append(treeNode.left)
            if treeNode.right:
                list.append(treeNode.right)
        return result

算法4,层次遍历,每一层在一行输出,“之”字型遍历二叉树

为了将每一层进行单独输出,需要统计这一行的个数toPrint,然后统计下一行的个数nextPrint
参考我之前的博客:https://blog.csdn.net/weixin_36372879/article/details/83994160

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if pRoot == None:
            return []
        queue = []
        toPrint = 1
        queue.append(pRoot)
        nextPrint = 0
        results = []
        result = []
        while queue != []:
            popNode = queue.pop(0)
            result.append(popNode.val)
            toPrint -= 1
            if popNode.left:
                queue.append(popNode.left)
                nextPrint += 1
            if popNode.right:
                queue.append(popNode.right)
                nextPrint += 1
            if toPrint == 0:
                results.append(result)  #这层遍历完毕,加入到结果中
                toPrint = nextPrint  #下层需要遍历的数据
                result = []   #这层遍历完毕,清零
                nextPrint = 0   #下下层清零
        return results

“之字形打印二叉树”:可以使用栈


算法5,根据前序序列和中序序列重建二叉树

算法思想就是:先序遍历的肯定是根节点,然后在中序遍历序列中,找到这个节点,将树的构造一分为二即可。

class TreeNode:
     def __init__(self, x):
         self.val = x
         self.left = None
         self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    def construct(self, pre, tin, startPre, endPre, startTin, endTin):
        if startPre <= endPre:
            root = TreeNode(pre[startPre])
            i = startTin
            while tin[i] != pre[startPre]:   #在中序遍历中,找到根节点,然后一分为二
                i += 1
            leftLength = i - startTin   #左子树的长度
            if leftLength:
                root.left = self.construct(pre, tin, startPre + 1, startPre + leftLength, startTin, i - 1)
            if endTin - i:
                root.right = self.construct(pre, tin, startPre + leftLength + 1, endPre, i + 1, endTin)
        return root
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        return self.construct(pre, tin, 0, len(pre) - 1, 0, len(tin) - 1)

算法6,二叉树和为某一值的路径(回溯遍历算法)

题目描述
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
算法思想:为了记住中间的遍历路径,使用一个数组来记录,最后判断数组的和,往左边遍历之后,需要回溯数组,然后往右边遍历

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回二维列表,内部每个列表表示找到的路径
    def __init__(self):
        self.results = []
    def ListSum(self, l):
        sum = 0
        for i in l:
            sum += i
        return sum
    def RecursionFindPath(self, root, expectNumber, result):
        result.append(root.val)
        temp = result[:]  #保存之前的结果
        if root.left == None and root.right == None and self.ListSum(result) == expectNumber:
            self.results.append(result)
        if root.left:
            self.RecursionFindPath(root.left, expectNumber, result)
        result = temp[:]  #回溯过程
        if root.right:
            self.RecursionFindPath(root.right, expectNumber, result)
    def QuickSort(self, results, start, end):   #对数组进行快速排序
        if start >= end:
            return
        low, high = start, end
        pivot = results[start]
        while low < high:
            while low < high and len(results[high]) <= len(pivot):
                high -= 1
            if low < high:
                results[low] = results[high]
            while low < high and len(results[low]) >= len(pivot):
                low += 1
            if low < high:
                results[high] = results[low]
        results[low] = pivot
        self.QuickSort(results, start, low - 1)
        self.QuickSort(results, low + 1, end)
    def FindPath(self, root, expectNumber):
        # write code here
        if root == None:
            return []
        self.RecursionFindPath(root, expectNumber, [])
        if self.results == []:
            return []
        self.QuickSort(self.results, 0, len(self.results) - 1)
        return self.results

测试:

root = TreeNode(1)
root.left = TreeNode(2)
root.left.left = TreeNode(4)
root.right = TreeNode(3)
root.right.right = TreeNode(2)
root.right.right.left = TreeNode(1)
root.right.right.right = TreeNode(5)
expectNum = 7
print(Solution().FindPath(root, expectNum))

输出:
在这里插入图片描述


算法7,遍历树的第k个节点

例如下面这个二叉搜索树,找出第k个节点
在这里插入图片描述
算法思想就是设置一个全局的k,然后使用中序遍历
需要注意的是代码的写法,不能根据k判断,而是要根据结果判断,因为需要先遍历,再k–。

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    def __init__(self):
        self.k = 0
    def InOrder(self, Root):
        ans = None
        if Root:
            if ans == None and Root.left:
                ans = self.InOrder(Root.left)   #往左遍历
            if ans == None and self.k == 1:
                ans = Root                      #遍历到目标节点
            if ans == None and self.k != 1:     #没有遍历到目标节点,k--
                self.k -= 1
            if ans == None and Root.right:      #往右遍历
                ans = self.InOrder(Root.right)
        return ans
    def KthNode(self, Root, k):
        if Root == None or k <= 0:
            return None
        self.k = k
        return self.InOrder(Root)

算法8,遍历倒数第k个节点

遍历倒数第k个节点,可以使用中序遍历,只不过先遍历右子树,再遍历左子树

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
class Solution:
    # 返回对应节点TreeNode
    def __init__(self):
        self.k = 0
    def ReverseInOrder(self, pRoot):
        ans = None
        if pRoot:
            if ans == None and pRoot.right:
                ans = self.ReverseInOrder(pRoot.right)
            if ans == None and self.k == 1:
                ans = pRoot
            if ans == None and self.k != 1:
                self.k -= 1
            if ans == None and pRoot.left:
                ans = self.ReverseInOrder(pRoot.left)
        return ans
    def KthNode(self, pRoot, k):
        # write code here
        if pRoot == None and k < 1:
            return None
        self.k = k
        return self.ReverseInOrder(pRoot)

算法9,树的子结构

博客:https://blog.csdn.net/weixin_36372879/article/details/83831191
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Tree1HasTree2(self, pRoot1, pRoot2):
        if pRoot2 == None:
            return True
        elif pRoot1 == None:
            return False
        if pRoot1.val == pRoot2.val:
            return self.Tree1HasTree2(pRoot1.left, pRoot2.left) and self.Tree1HasTree2(pRoot1.right, pRoot2.right)
        else:
            return False
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        if pRoot1 == None or pRoot2 == None:
            return False
        ans = False
        if pRoot1.val == pRoot2.val:
            ans = self.Tree1HasTree2(pRoot1, pRoot2)
        if ans == False:
            ans = self.Tree1HasTree2(pRoot1.left, pRoot2)
        if ans == False:
            ans = self.Tree1HasTree2(pRoot1.right, pRoot2)
        return ans

算法10 二叉树的镜像(将二叉树的左子树和右子树交换)

在这里插入图片描述

class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if root == None:
            return None
        if root.left == None and root.right == None:
            return root
        root.left, root.right = self.Mirror(root.right), self.Mirror(root.left)
        return root

算法11 对称二叉树

判断二叉树是否对称。

class Solution:
    def RecursionSymmetry(self, root1, root2):
        if root1 == None and root2 == None:
            return True
        elif root1 == None or root2 == None:
            return False
        if root1.val == root2.val:
            return self.RecursionSymmetry(root1.left, root2.right)
        else:
            return False
    def isSymmetrical(self, pRoot):
        # write code here
        return self.RecursionSymmetry(pRoot, pRoot)

猜你喜欢

转载自blog.csdn.net/weixin_36372879/article/details/85918490