03-树3 Tree Traversals Again (25 分)

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.


Figure 1

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: “Push X” where X is the index of the node being pushed onto the stack; or “Pop” meaning to pop one node from the stack.

Output Specification:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:

3 4 2 6 5 1

Code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 31 //TREE从1开始存储有效结点,下标为0表示NULL
#define Push "Push" //定义字符串宏常量
#define Pop "Pop"
/*栈*/
struct SNode
{
    int Data[MAXSIZE];
    int Top;
};
/*树*/
typedef struct TreeNode *BinTree;
struct TreeNode
{
    int Left;
    int Right;
}Tree[MAXSIZE];
int CNT=0;

void PostorderTraversal(int ROOT);
int ReadTree();

int main()
{
    /* 1.按照中序遍历读入二叉树 2.找出根节点 3.从根节点开始后序遍历,输出结点 */
    int root;
    root = ReadTree();
    PostorderTraversal(root);
    return 0;
}

/*按照中序遍历读入二叉树,并返回根节点*/
int ReadTree()
{
    int N,t,j=1;
    scanf("%d",&N);
    int tmp[N];  //用于存储结点Push顺序
    
    /*初始化栈*/
    struct SNode *S;
    S = (struct SNode *)malloc(sizeof(struct SNode));
    S->Top = -1;
    
    char *ch[2*N]; //字符指针数组,用于存储键盘输入的Push or Pop操作字符
    /*第一个Push结点为根节点,入栈*/
    ch[0] = (char *)malloc(sizeof(char)*5);
    scanf("\n%s",ch[0]);
    scanf("%d",&tmp[0]);
    S->Top++;
    S->Data[S->Top] = tmp[0];
    if(N){
            //构造空树
        for(int i=1;i<=N;i++)
        {
            Tree[i].Left =0;
            Tree[i].Right=0;
        }

        for(int i=1;i<=2*N-1;i++)
        {
            /*算法: 1.第一个结点必为Push操作,先存储 2.继续输入,结点若为Push操作,入栈,并判断上一个操作: 若为Push,則该结点为上一个结点的左儿子; 若为Pop,則该结点为上一个Pop结点的右儿子; 结点若为Pop操作,出栈。 3.循环第二步,直到栈空。 */
            ch[i] = (char *)malloc(sizeof(char)*5);
            scanf("\n%s",ch[i]);
            if(strcmp(ch[i],Push)==0)
            {
                scanf("%d",&tmp[j]);
                S->Top++;
                S->Data[S->Top] = tmp[j];
// printf("S->Top =%d,S->Data[%d] = %d\n",S->Top,S->Top,S->Data[S->Top]);
                if(strcmp(ch[i-1],Push)==0)
                {
                    Tree[tmp[j-1]].Left = tmp[j];
// printf("Tree[%d].Left = %d\n",tmp[j-1],Tree[tmp[j-1]].Left);
                }else if(strcmp(ch[i-1],Pop)==0)
                {
                    Tree[t].Right = tmp[j];
// printf("Tree[%d].Right = %d\n",t,Tree[t].Right);
                }
                j++;

            }else if(strcmp(ch[i],Pop)==0)
            {
                t = S->Data[S->Top];
// printf("Pop = %d\n",t);
                S->Top--;
// printf("S->Top =%d\n",S->Top);
            }
        }
    }
    return tmp[0];
}

void PostorderTraversal(int ROOT)
{
    if( ROOT!=0 ) {
        PostorderTraversal(Tree[ROOT].Left);
        PostorderTraversal( Tree[ROOT].Right );
        if(CNT == 0)
            printf("%d", ROOT);
        else
            printf(" %d", ROOT);
        CNT++;
    }
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务