数据结构——二叉树的非递归遍历

1、问题描述

二叉树的非递归遍历可通过栈来实现。例如对于由abc##d##ef###先序建立的二叉树,如下图1所示,中序非递归遍历可以通过如下一系列栈的入栈出栈操作来完成:push(a) push(b) push(c) pop pop push(d)pop pop push(e) push(f) pop pop。如果已知中序遍历的栈的操作序列,就可唯一地确定一棵二叉树。请编程输出该二叉树的后序遍历序列。

2、题目要求

输入:

第一行一个整数 n,表示二叉树的结点个数。接下来 2n 行,每行描述一个栈操作,格式为:push X 表示将结点 X 压入栈中,pop 表示从栈中弹出一个结点(X 用一个字符表示)。
输出:
一行,后序遍历。

3、样例输入输出

样例输入:

6

push a

push b

push c

pop

pop

push d

pop

pop

push e

push f

pop

pop

样例输出:

cdbfea

4、题目分析

(1)首先需要建立一棵二叉树,我使用的是先序遍历的方法建立二叉树。在建立二叉树的函数中,定义字符串类型ch(用于输入pop/push),定义字符类型c(用于输入存放的元素)。当ch为pop时二叉树结点T置为NULL,当ch为push时输入c,T->date=c,递归构造左右子树。

(2)定义一个二叉树类型的栈,用于辅助pop和push的运行。

(3)最后设计一个函数将date域中的数据后序遍历并输出。

5、详细代码

#include<iostream>
#define OK 1
#define ERROR 0
#define MAXSIZE 100
using namespace std;
 
//定义二叉树类型
typedef struct BiNode {
    char date;//存放数据
    struct BiNode* lchild, * rchild;//左右孩子指针
}BiNode, * BiTree;
 
//初始化二叉树
int InitTree(BiTree& T)
{
    T = new BiNode;
    if (!T) return ERROR;
    T->lchild = T->rchild = NULL;
    return OK;
}
 
//建立二叉树
BiTree SetTree(int& n,int &m)
{
    BiTree T = nullptr;
    string ch;//ch为操作
    char e;//e为输入的字符
    if (n != 0)
    {
        cin >> ch;
        if (ch == "pop")
        {
            m++;
            T = NULL;
        }
        else
        {
            cin >> e;
            T = new BiNode;
            T->date = e;
            n--;
            T->lchild = SetTree(n,m);//构造左子树
            T->rchild = SetTree(n,m);//构造右子树
        }
    }
    return T;
}
 
struct BiNode* s[MAXSIZE];//定义栈
int top = -1;//栈顶计数
 
//入栈
int s_Push(BiTree e)
{
    if (top == 99)
        return ERROR;//栈满
    s[++top] = e;
    return OK;
}
 
//出栈
BiTree s_Pop()
{
    if (top == -1) return ERROR;
    BiTree e;
    e = s[top];
    top--;
    return e;
}
 
struct BiNode* st[MAXSIZE];//定义栈
int top2 = -1;//栈顶计数
 
//入栈
int st_Push(BiTree e)
{
    if (top2 == 99)
        return ERROR;//栈满
    st[++top2] = e;
    return OK;
}
 
//出栈
BiTree st_Pop()
{
    if (top2 == -1) return ERROR;
    BiTree e;
    e = st[top2];
    top2--;
    return e;
}
 
void PostOrderIter(BiTree& T)
{
    BiTree t;
    BiTree p;
    s_Push(T);
    while (top != -1)
    {
        t = s_Pop();
        st_Push(t);
        if (t->lchild)
            s_Push(t->lchild);
        if (t->rchild)
            s_Push(t->rchild);
    }
    while (top2 != -1)
    {
        p = st_Pop();
        cout << p->date;
    }
    cout << endl;
}
 
int main()
{
    BiTree T;
    int m = 0;
    int n;
    cin >> n;
    T = SetTree(n,m);
    char ch;
    cin >> ch;
    PostOrderIter(T);
    return 0;
}

补充:上述代码有个bug,就是当把样例输入时,总是要自己在多加一个pop才能输出,为了解决这个问题,我使用了n(操作个数),将它传给建立二叉树的函数,然后直接在主函数中进行最后一步pop操作。我想了一段时间,没有想到更好的办法,如果读者有更好的方法,可以在评论区告诉我哦!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值