二叉树重建及二叉树广度优先遍历

#include <iostream>
#include <queue>
using namespace std;

//树节点类
class TNode
{
public:
    TNode *left, *right;
    char value;
    TNode()
    {
        left = right = NULL;
    }

    TNode(char v)
    {
        left = right = NULL;
        value = v;
    }

};

//根据二叉树的先序遍历和中序遍历重建二叉树
//PreOrder为二叉树的先序遍历 InOrder为二叉树中序遍历
TNode* RebuildTree(string PreOrder, string InOrder)
{
    //先序遍历中第一个元素为根
    TNode* root = new TNode(PreOrder[0]);

    //只剩一个节点的情况 直接返回节点
    if (PreOrder.length() <= 1)
        return root;

    //在中序遍历中找到根 根左边的部分为左子树 右边的部分为右子树
    string LeftChild = InOrder.substr(0, InOrder.find(PreOrder[0]));
    string RightChild = InOrder.substr(InOrder.find(PreOrder[0])+1);

    //递归建立左右子树
    if (LeftChild.length())
        root->left = RebuildTree(PreOrder.substr(1, LeftChild.length()), LeftChild);
    if (RightChild.length())
        root->right = RebuildTree(PreOrder.substr(1 + LeftChild.length()), RightChild);

    return root;
}

//二叉树先序遍历
void PrevOrder(TNode *root)
{
    if(root == NULL)
        return;
    //访问根
    cout << root->value;
    //访问左子树
    if(root->left)
        PrevOrder(root->left);
    //访问右子树
    if(root->right)
        PrevOrder(root->right);
}

//二叉树中序遍历
void InOrder(TNode *root)
{
    if(root == NULL)
        return;
    //访问左子树
    if(root->left)
        InOrder(root->left);
    //访问根
    cout << root->value;
    //访问右子树
    if(root->right)
        InOrder(root->right);
}

//二叉树后序遍历
void PostOrder(TNode *root)
{
    if(root == NULL)
        return;
    //访问左子树
    if(root->left)
        PostOrder(root->left);
    //访问右子树
    if(root->right)
        PostOrder(root->right);
    //访问根
    cout << root->value;
}  

//二叉树层次遍历
void BFS(TNode *root)
{
    //用队列储存
    queue<TNode*> nodes;
    //根节点入队
    nodes.push(root);

    while (!nodes.empty())
    {
        TNode* top = nodes.front();
        //输出队头元素
        cout << top->value;
        //左子树入队
        if (top->left)
            nodes.push(top->left);
        //右子树入队
        if (top->right)
            nodes.push(top->right);
        //弹出队头
        nodes.pop();
    }
    cout << endl;
}

int main()
{
    string Prev, In;
    int t;
    cin >> t;
    while (t--)
    {
        cin >> Prev >> In;
        TNode *root = RebuildTree(Prev, In);
        cout << "PreOrder: ";
        PrevOrder(root);
        cout << endl << "InOrder: ";
        InOrder(root);
        cout << endl << "PostOrder: ";
        PostOrder(root);
        cout << endl << "BFS: ";
        BFS(root);
        cout << endl;
    }
    return 0;
}

需求分析:

输入一棵二叉树的先序遍历序列和中序遍历序列,输出它的先序遍历、中序遍历、后序遍历和广度优先遍历序列。

概要设计

先定义树节点类,使用链表储存方式:

class TNode

{

public:

TNode *left, *right;

char value;

TNode()

{

left = right = NULL;

}

TNode(char v)

{

left = right = NULL;

value = v;

}

};

 对于二叉树T,可以递归定义它的先序遍历、中序遍历和后序遍历如下:

PreOrder(T)=T的根节点+PreOrder(T的左子树)+PreOrder(T的右子树)

InOrder(T)=InOrder(T的左子树)+T的根节点+InOrder(T的右子树)

PostOrder(T)=PostOrder(T的左子树)+PostOrder(T的右子树)+T的根节点

其中加号表示字符串连接运算。例如,对下图所示的二叉树,先序遍历为DBACEGF,中序遍历为ABCDEFG,后序遍历为ACBFGED。

D

/ \

B   E

/  \  / \

A  C G F

重建二叉树:

因为已经给出二叉树的先序遍历和中序遍历,先序遍历的第一个节点是根节点,然后在中序遍历中找到根,根左边的部分为左子树,右边的部分为右子树 ,然后按照这个过程递归建立左右子树即可。

广度优先遍历二叉树:

用队列保存当前访问节点,先把根节点入队,当队列非空时,访问队头节点并把该节点的左右孩子入队后弹出队头元素,直到队列为空

程序输入:

第一行为一个整数t(0<t<10),表示测试用例个数。 以下t行,每行输入一个测试用例,包含两个字符序列s1和s2,其中s1为一棵二叉树的先序遍历序列,s2为中序遍历序列。s1和s2之间用一个空格分隔。序列只包含大写字母,并且每个字母最多只会出现一次,程序输出它的先序遍历、中序遍历、后序遍历和广度优先遍历序列。

Sample Input

2 DBACEGF ABCDEFG BCAD CBAD

Sample Output

PreOrder: DBACEGF

InOrder: ABCDEFG

PostOrder: ACBFGED

BFS: DBEACGF

PreOrder: BCAD

InOrder: CBAD

PostOrder: CDAB

BFS: BCAD

测试结果

附录

时间: 2024-10-13 04:03:22

二叉树重建及二叉树广度优先遍历的相关文章

二叉树的深度优先和广度优先遍历

深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止.如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止. 二叉树的深度优先遍历和先序遍历结果一样的. 思想是采用栈, 首先将根结点压入栈,如果栈不为空,而后出栈并输出当前结点中值,而后先把右子树

二叉树重建 - (先序遍历、中序遍历、后序遍历)

对于一棵二叉树T,我们可以递归定义它的先序遍历,中序遍历,后序遍历:  1.先序遍历  ( PreOrder(T) = T的根节点 + PreOrder(T的左子树) + PreOrder(T的右子树) ) 2.中序遍历  ( InOrder(T) = InOrder(T的左子树) + T的根节点 +  InOrder(T的右子树) ) 3.后序遍历  ( PostOrder(T) = PostOrder(T的左子树) + PostOrder(T的右子树)  + T的根节点 ) 其中,加号表

二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有深度遍历和广度遍历,深度遍历有前序.中序以及后序三种遍历方法,广度遍历即我们平常所说的层次遍历.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁,而对于广度遍历来说,需要其他数据结构的支撑,比如堆了.所以,对于一段代码来说,可读性有时候要比代码本身的效率要重要的多. 四种主要的遍历思想为: 前序遍历:根结点 ---> 左子树 ---> 右子树 中序遍历:左子

二叉树的深度优先遍历和广度优先遍历

1. 二叉树的深度优先遍历,使用栈Stack, DFS(Depth First Search) function DFS(root){ var stack = []; stack.push(root); var node = null; while(stack.length){ node = stack.pop(); //visit node.data; if(node.right){ stack.push(node.right); } if(node.left){ stack.push(nod

C++ 二叉树深度优先遍历和广度优先遍历

二叉树的创建代码==>C++ 创建和遍历二叉树 深度优先遍历:是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. //深度优先遍历二叉树void depthFirstSearch(Tree root){ stack<Node *> nodeStack; //使用C++的STL标准模板库 nodeStack.push(root); Node *node; while(!nodeStack.empty()){ node = nodeStack.top(); printf(format, n

UVA 548(二叉树重建与遍历)

J - Tree Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Appoint description:  System Crawler  (2014-05-16) Description  Tree  You are to determine the value of the leaf node in a given binary tree that is the ter

广度优先遍历二叉树

 // //广度优先遍历二叉树 // //从一个顶点开始,识别所有可到达顶点 // //的方法叫作广(宽)度优先搜索,这种 // //搜索可使用队列来实现 typedef struct binarytree { EleType data; struct binarytree *LeftChild; struct binarytree *RightChild; }Tree; // class Node { Tree t; Node next; }; // class Queue { Node

二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式

二叉树的遍历方式: 1.深度优先:递归,非递归实现方式 1)先序遍历:先访问根节点,再依次访问左子树和右子树 2)中序遍历:先访问左子树,再访问根节点吗,最后访问右子树 3)后序遍历:先访问左子树,再访问右子树,最后访问根节点 2.广度优先     按照树的深度,一层一层的访问树的节点 1 package Solution; 2 3 import java.util.LinkedList; 4 import java.util.Queue; 5 import java.util.Stack; 6

转:二叉树的深度优先遍历和广度优先遍历

转自:http://www.blogjava.net/fancydeepin/archive/2013/02/03/395073.html 深度优先搜索算法(Depth First Search),是搜索算法的一种.是沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点.这一过程一直进行到已发现从源节点可达的所有节点为止. 如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为