现在的位置: 首页 > 综合 > 正文

ACMclub 1757 二叉链表存储的二叉树 – from lanshui_Yang

2019年01月07日 ⁄ 综合 ⁄ 共 2092字 ⁄ 字号 评论关闭
文章目录

题目描述:

在本题中,将会给出一个按照先序遍历得出的字符串,空格代表空的子节点,大写字母代表节点内容。请通过这个字符串建立二叉树,并按照题目描述中的一种先序遍历和两种中序遍历的算法分别输出每一个非空节点。

输入格式

输入只有一行,包含一个字符串S,用来建立二叉树。保证S为合法的二叉树先序遍历字符串,节点内容只有大写字母,且S的长度不超过100。

输出

共有三行,每一行包含一串字符,表示分别按先序、中序、中序得出的节点内容,每个字母后输出一个空格。请注意行尾输出换行。

样例输入

ABC  DE G  F   

样例输出

A B C D E G F 
C B E G D F A 
C B E G D F A 

求解思路:本题有一个难点和一个坑! 难点是指输入和建树的问题,具体解决方法请看程序;解决完输入,建好树,如何进行遍历,有两种方法:第一种:直接递归(比较简单,不再详述) ; 第二种:手动调用栈(有一点需要注意的地方,请看程序!!)

        直接递归遍历的程序如下:

#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std ;
const int MAXN = 1111111 ;
struct Node
{
    char data ;
    int xu ;
    Node *left ;
    Node *right ;
    Node(): data('\0') , xu(0) , left(NULL) , right(NULL) {} ;
} ;
int flag ;
Node *stap[MAXN] ;
int top ;
void creatTree(Node *&T) // 注意:此处的输入和建树方式
{
    if(flag) return ;
    char tmp ;
    tmp = getchar() ;
    if(tmp == ' ')
    {
        T = NULL ;
    }
    else if(tmp == '\n')
    {
        flag = 1 ;
        return ;
    }
    else
    {
        T = new Node ;
        T -> data = tmp ;
        creatTree(T -> left) ;
        creatTree(T -> right) ;
    }
}
void initV(Node *p)
{
    if(p)
    {
        cout << p -> data << " " ;
        initV(p -> left) ;
        initV(p -> right) ;
    }
}
void midV(Node *p)
{
    if(p)
    {
        midV(p -> left) ;
        cout << p -> data << " " ;
        midV(p -> right) ;
    }
}
int main()
{
    flag = 0 ;
    Node *head ;
    creatTree(head) ;
    initV(head) ;
    cout << endl ;
    midV(head) ;
    cout << endl ;
    midV(head) ;
    cout << endl ;
    return 0 ;
}

     第二种:手动调用栈

#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std ;
const int MAXN = 1111111 ;
struct Node
{
    char data ;
    int xu ;
    Node *left ;
    Node *right ;
    Node(): data('\0') , xu(0) , left(NULL) , right(NULL) {} ;
} ;
int flag ;
Node *stap[MAXN] ;
int top ;
void creatTree(Node *&T)
{
    if(flag) return ;
    char tmp ;
    tmp = getchar() ;
    if(tmp == ' ')
    {
        T = NULL ;
    }
    else if(tmp == '\n')
    {
        flag = 1 ;
        return ;
    }
    else
    {
        T = new Node ;
        T -> data = tmp ;
        creatTree(T -> left) ;
        creatTree(T -> right) ;
    }
}
void initV(Node *p)
{
    if(p)
    {
        cout << p -> data << " " ;
        initV(p -> left) ;
        initV(p -> right) ;
    }
}
void mid2V(Node *p)
{
    top = -1 ;
    if(p) stap[++ top] = p ;
    Node *tmp ;
    while (top >= 0)
    {
        tmp = stap[top] ;
        while (tmp)
        {
                stap[++ top] = tmp -> left ;
                tmp = tmp -> left ;
        }
        top -- ; // 将空指针退栈
                 // 注意:此处非常重要,空指针退栈意义不只是 上面程序显示的节点的左子树 访问完
                 // 也可能是 下面 所示 的 节点的右子树 访问完 !!
        if(top >= 0)
        {
            tmp = stap[top --] ;
            cout << tmp -> data << " " ;
            stap[++ top] = tmp -> right ;
        }
    }
}
int main()
{
    flag = 0 ;
    Node *head ;
    creatTree(head) ;
    initV(head) ;
    cout << endl ;
    mid2V(head) ;
    cout << endl ;
    mid2V(head) ;
    cout << endl ;
    return 0 ;
}

抱歉!评论已关闭.