数据结构之二叉树的遍历和构造

数据结构------二叉树

本文使用python语言实现

目录图示:

在这里插入图片描述

本文所用二叉树图示:

在这里插入图片描述
来先做一下这道题:

	       先序遍历为:  ABDEFGCHK
	       中序遍历为:  DBFEGACKH
	       后序遍历为:  DFGEBKHCA
	       层次遍历为:  ABCDEHFGK
0> 树节点的定义:
class TreeNode:
    def __init__(self, x=None,left=None,right=None):
        self.val = x
        self.left = left
        self.right = right
1> 先序遍历:
def preorderTraversal(root): #先序 迭代
    if root is None:
        return []
    stack, output = [root, ], []
    while stack:
        root = stack.pop()
        output.append(root.val)
        if root.right is not None:
            stack.append(root.right)
        if root.left is not None:
            stack.append(root.left)
    return output

def preorderTraversal1(root): #先序 递归
    output = []
    def helper(root):
        if not root: return
        output.append(root.val)
        helper(root.left)
        helper(root.right)
    helper(root)
    return output
2> 中序遍历:
def inorderTraversal(root): #中序迭代
    if root is None:
        return []
    stack, output = [], []
    while stack or root:  # 栈为空并且目前的节点为空则结束
        while root:  # 遍历左节点,一路到底
            stack.append(root)
            root = root.left
        if stack:  # 取出到头的那个左孩子,再返回while找右孩子的左孩子一路到底,要是没有右则继续出栈
            a = stack.pop()
            output.append(a.val)
            root = a.right
    return output

def inorderTraversal1(root): #中序递归
    output = []
    def helper(root):
        if not root:
            return
        helper(root.left)
        output.append(root.val)
        helper(root.right)
    helper(root)
    return output
3> 后序遍历:
def postorderTraversal(root):#后序迭代
    if root is None:                # 可以看作前序遍历(先左子树后右子树) 先遍历右子树再左子树(先左入栈), 输出倒序
        return []
    stack, output = [root, ], []
    while stack:
        root = stack.pop()
        output.append(root.val)
        if root.left is not None:
            stack.append(root.left)
        if root.right is not None:
            stack.append(root.right)
    return output[::-1]

def postorderTraversal1(root):#后序递归
    output = []
    def helper(root):
        if not root:
            return
        helper(root.left)
        helper(root.right)
        output.append(root.val)
    helper(root)
    return output
4> 层次遍历:
def levelOrder(root): #层次递归
    if root is None:
        return []
    levels = []
    def inlevels(node, level):
        if len(levels) == level:            #树是0级一级二级 对应levels的长度为1 2 3 当长度和目前的级数相等时,说明树的这一级还没地方放 要append
            levels.append([])
        levels[level].append(node.val)
        if node.left is not None:
            inlevels(node.left,level+1)
        if node.right is not None:
            inlevels(node.right,level+1)
    inlevels(root, 0)
    return levels

def levelOrder1(root): #层次迭代
    levels = []
    if not root:
        return levels
    level = 0
    queue = deque([root, ])
    while queue:
        levels.append([])
        level_length = len(queue)          #这一级的节点数
        for i in range(level_length):
            node = queue.popleft()
            levels[level].append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        level += 1
    return levels

测试如下:

if __name__=='__main__':
    root = TreeNode('A', TreeNode('B', TreeNode('D'),TreeNode('E', TreeNode('F'), TreeNode('G'))),TreeNode('C', right=TreeNode('H', left=TreeNode('K'))))
    a = preorderTraversal(root);print('先序遍历迭代:', a)
    a = preorderTraversal1(root);print('先序遍历递归:', a)
    a = inorderTraversal(root);print('中序遍历迭代:', a)
    a = inorderTraversal1(root);print('中序遍历递归:', a)
    a = postorderTraversal(root);print('后序遍历迭代:', a)
    a = postorderTraversal1(root);print('后序遍历递归:', a)
    a = levelOrder(root);print('层次遍历递归:', a)
    a = levelOrder(root);print('层次遍历迭代:', a)

运行结果如下:
啥描述啊啊啊啊啊

5>构造二叉树

构造二叉树即已知先序遍历中序遍历后序遍历的其中两个,依此来构造二叉树。

1.已知一棵树的中序遍历inorder和后序遍历postorder(均为列表形式):
中序遍历为左中右,后序遍历为左右中,即根节点root的值为postorder[-1],设为val,然后找到val在inorder中的索引i,左边为左子树,右边为右子树

      inorder 为:[左子树的中序遍历 val 右子树的中序遍历]
    postorder 为:[左子树的后序遍历 右子树的后序遍历 val]

然后 迭代
root.left的新inorder为inorder[:i],新postorder为postorder[:i]
root.right的新inorder为inorder[i+1:],新postorder为postorder[i:-1]

代码如下:

def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        if not inorder or not postorder:
            return None
        val = postorder[-1]
        root = TreeNode(val)
        i = inorder.index(val)
        root.left = self.buildTree(inorder[:i],postorder[:i])
        root.right = self.buildTree(inorder[i+1:],postorder[i:-1])
        return root

2.已知一棵树的先序遍历preorder和中序遍历inorder:
和上一个类似

      preorder 为:[val 左子树的中序遍历 右子树的中序遍历]
       inorder 为:[左子树的后序遍历 val 右子树的后序遍历]

代码如下:

def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if not preorder or not inorder:
            return None
        val = preorder[0]
        root = TreeNode(val)
        i = inorder.index(val)
        root.left = self.buildTree(preorder[1:i+1],inorder[:i])
        root.right = self.buildTree(preorder[i+1:len(preorder)],inorder[i+1:])
        return root

3.已知一棵树的先序遍历preorder和后序遍历postorder:
这种情况得出的结果可能不止一个!(除非每个根节点都有两个子节点)
举例如下:

     先序遍历为ABCD
     后序遍历为BDCA

可能会有以下两种结情况:
在这里插入图片描述
在这里插入图片描述
代码如下:

def buildTree(self, pre: List[int], post: List[int]) -> TreeNode:
       if not pre: return None
       root = TreeNode(pre[0])
       if len(pre) == 1: return root    #!!!!!!!!!!!!!!!!!!!!!!!!!!!

       i = post.index(pre[1]) + 1
       root.left = self.buildTree(pre[1:i+1], post[:i])
       root.right = self.buildTree(pre[i+1:], post[i:-1])
       return root
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值