美文网首页
算法 | 二叉树的构建与遍历

算法 | 二叉树的构建与遍历

作者: yuanCruise | 来源:发表于2018-12-28 12:48 被阅读12次

0.简介

对于二叉树的遍历,有四种方式:层序输出,前序输出,中序输出,后序输出。但不论利用何种输出方式对二叉树进行遍历,其前提为必须提前已知一颗树。那么什么叫做已知一颗树呢?
所谓已知一棵树的意思即为:已经用数据结构定义好的树,通过该树可以知道哪个节点是根;哪个节点是左儿子,右儿子;哪个节点是左儿子的左右儿子等等这样的信息。在本文中,我们把得到这个已知树的过程称之为创建一颗树。

1.四种遍历方式示意图

2.如何构建一颗已知二叉树

利用层序输入的策略构建二叉树相对比较方便。当然也可以通过其他手段构建二叉树,但相对会比较麻烦,该种策略是最容易理解的。后续的实例中会介绍另外一种构建策略。


"""
#定义好节点类
#默认节点为空,利用重写构造函数的策略,使得每次定义一个节点,
#对应节点都包含了元素,左右儿子。
"""
class Node(object):#新式类
    def __init__(self,elem=-1,lchild=None,rchild=None):
        self.elem = elem
        self.lchild = lchild
        self.rchild = rchild
"""
#定义树类
#每颗树的构造函数都会初始化一个根节点
#并且会利用层序的策略定义添加节点构建已知树函数
"""
class Tree(object):
    def __init__(self, root=None):
        self.root = root
        self.MyQueue = []
    #把一个节点添加到树中的策略(层序)
    def add(self,elem):
        #定义一个带有给定元素elem的节点
        node = Node(elem)
        if self.root.elem == -1:#如果树是空的
            self.root = node #那么当前节点就是根节点
            self.MyQueue.append(self.root)#并把当前根节点放入自己构造的队列中
        #如果当前树为非空
        else:
            #把当前队列中的第一个节点取出来
            treeNode = self.MyQueue[0]
            #如果取出的节点没有左子树,则把当前节点赋值给取出节点的左子树,
            #并将该节点加入到自制对列中(因为后续还要给该节点添加左右子树)
            if treeNode.lchild == None:
                treeNode.lchild = node
                self.MyQueue.append(treeNode.lchild)
            #如果取出的节点已经有左子树了,那就把当前节点赋值给其右子树
            #并将该节点加入到自制对列中(因为后续还要给该节点添加左右子树)
            #而和左子树插入不同,右子树插入后,当前被取出节点就被填满了(因为是二叉树),
            #所以该被取出节点需要从自制队列中弹出(注意这就是用对列不用栈的原因:先进先出)
            else:
                treeNode.rchild = node
                self.MyQueue.append(treeNode.rchild)
                self.MyQueue.pop(0)
if __name__ == '__main__':
    tree = Tree()
    tree.add(A)
    tree.add(B)
    tree.add(C)
    tree.add(D)
    tree.add(E)        
    tree.add(F)
    tree.add(G)  

3.根据已知二叉树遍历输出

层序输出:利用队列进行层序输出

def level(self):
    if self.root == None:
        return
    MyQueue = []
    node =self.root
    MyQueue.append(node)
    while MyQueue:
        node = MyQueue.pop(0)
        print node.elem
        if node.lchild:
            MyQueue.append(node.lchild)
        if node.rchild:
            MyQueue.append(node.rchild)

前序输出:根据父节点--左节点--右节点的顺序输出(利用递归)
中序输出:根据左节点--父节点--右节点的顺序输出(利用递归)
后序输出:根据左节点--右节点--父节点的顺序输出(利用递归)

def front(self):
    if self.root == None:
        return
    print self.root.elem
    self.front(self.root.lchild)
    self.front(self.root.rchild)
    
    
def middle(self):
    if self.root == None:
        return
    self.front(self.middle.lchild)
    print self.root.elem
    self.front(self.middle.rchild)
    
def post(self):
    if self.root == None:
        return
    self.front(self.middle.lchild)
    self.front(self.middle.rchild)
    print self.root.elem

4.创建二叉树并遍历输出实例

比如我们在笔试的过程中会遇到的题目:已知一颗树的前序遍历和中序遍历,输出二叉树的层序遍历。该类题目的策略就是通过树的前序遍历和中序遍历来创建一颗已知树,并通过创建得到的树进行层序的遍历输出。
解题思路:利用递归的手段通过前序和中序的结果来构建已知树。并利用广度优先的手段遍历输出(就是层序遍历)。之所以可以利用递归,因为当根据前序遍历结果可知,第一位是整颗树的根节点,而根据中序遍历中找到当前这个第一位的index,在中序遍历序列中该index之前和之后的两段被切分成了两颗子树,并且根据这两颗子树的长度可以从前序的列表中切除这两颗子树的前序遍历列表,因此我们发现对于每一个节点的操作一致,且最终的终止条件为最原始的前序为空时递归结束。

import sys

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


def buildTree(preTree, inTree):
    if preTree:
        root = Node(preTree[0])
        index = inTree.index(preTree[0])

        root.left = buildTree(preTree[1:index + 1], inTree[:index])
        root.right = buildTree(preTree[index + 1:], inTree[index + 1:])
        return root
    else:
        return None


n = int(sys.stdin.readline())
preTree = sys.stdin.readline().split()
inTree = sys.stdin.readline().split()
root = buildTree(preTree, inTree)

queue = [root]
nextqueue = []

try:
    while queue:
        for Node in queue:
            print Node.val
            if Node.left:
                nextqueue.append(Node.left)
            if Node.right:
                nextqueue.append(Node.right)
        queue, nextqueue = nextqueue, []
except:
    pass

给自己打个小广告

本人211硕士毕业生,目前从事深度学习,机器学习计算机视觉算法行业,目前正在将我的各类学习笔记发布在我的公众号中,希望感兴趣一起学习的同学们可以关注下~~~
本人微信公众号:yuanCruise


相关文章

  • 二叉树——遍历

    一、原理 二、实验 实验1 根据二叉树的先根遍历序列数组信息,写出构建下图的二叉树算法,再采用中根遍历,写出遍历后...

  • 二叉树的遍历

    关于二叉树的算法问题,一般都以二叉树的遍历为基础,这里给出二叉树的多种遍历方式 树结构: 树结点的定义及其构建: ...

  • 二叉树遍历(递归算法和非递归算法)

    实验三 二叉树遍历(递归算法和非递归算法) 一.实验目的 1.掌握二叉树的存储结构与基本操作 2.掌握二叉树的遍历...

  • Java中用递归和迭代实现二叉树的中序( InOrder )遍历

    与数组和链表不同,二叉树有几种遍历方式。遍历算法大致分为深度优先和广度优先遍历算法,这取决于算法实际如何工作。顾名...

  • 二叉树的三种深度优先遍历算法与思路

    看了一些关于二叉树遍历算法的文章,例如:二叉树三种遍历方式的递归和循环实现二叉树的递归与非递归遍历(前序、中序、后...

  • 算法-二叉树算法总结

    二叉树算法总结 1 二叉树的遍历 1.1 前序遍历 递归 迭代 1.2 中序遍历 递归 迭代 1.3 后序遍历 递...

  • 构建求和树——二叉树的构建及遍历

    一、相关概念 二、题目 题目 思路 利用二叉树的前序、中序遍历序列构建二叉树,并遍历构建好的二叉树。 利用递归的思...

  • ALI 算法

    二叉树遍历算法: 按层遍历, 中序前序后序:

  • 二叉树的遍历

    二叉树的遍历 二叉树常用的遍历方式有:前序遍历、中序遍历、后序遍历、层序遍历四种遍历方式,不同的遍历算法,其思想略...

  • 二叉树的中序遍历(Java)——Morris迭代算法

    二叉树的中序遍历 对于此题而言,若采用递归算法(简单),我们使用深度优先算法来遍历二叉树。若采用迭代算法,我们使用...

网友评论

      本文标题:算法 | 二叉树的构建与遍历

      本文链接:https://www.haomeiwen.com/subject/zhzjlqtx.html