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

题目描述:

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

输入格式

输入只有一行,包含一个字符串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 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值