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 <unistd.h>
#include <string.h>

typedef struct TreeNode *BinTree;
struct TreeNode {
    int Data;
    BinTree Left;
    BinTree Right;
};

//声明TreeNode,并且BinTree是指向其的指针

typedef struct SNode *Stack;
struct SNode {
    BinTree Data;
    Stack Next;
};

//声明SNode结构体,并且Stack是指向其的指针

BinTree CreateBinTree(int data);
int IsEmptyBinTree(BinTree BST);
void InsertLeftLeafe(BinTree BST, int leftData);
void InsertRightLeafe(BinTree BST, int rightData);

Stack CreateStack();
int IsEmptyStack(Stack S);
void StackPush(Stack S, BinTree pos);
BinTree StackPop(Stack S);
void PrintStack(Stack S);

BinTree Read();

BinTree CreateBinTree(int data)
{
    BinTree head;
    head = (BinTree)malloc(sizeof(struct TreeNode));
    head->Data = data;
    head->Left = NULL;
    head->Right = NULL;
    return head;
}

int IsEmptyBinTree(BinTree BST)
{
    return (BST == NULL);
}

void InsertLeftLeafe(BinTree BST, int leftData)
{
    BinTree left;
    left = (BinTree)malloc(sizeof(struct TreeNode));
    left->Data = leftData;
    left->Left = NULL;
    left->Right = NULL;
    BST->Left =  left;
}

void InsertRightLeafe(BinTree BST, int rightData)
{
    BinTree right;
    right = (BinTree)malloc(sizeof(struct TreeNode));
    right->Data = rightData;
    right->Left = NULL;
    right->Right = NULL;
    BST->Right =  right;
}

Stack CreateStack()
{
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->Data = NULL;
    S->Next = NULL;
    return S;
}

int IsEmptyStack(Stack S)
{
    return (S->Next == NULL);
}

void StackPush(Stack S, BinTree pos)
{
    Stack TmpCell = (Stack)malloc(sizeof(struct SNode));
    TmpCell->Data = pos;
    TmpCell->Next = S->Next;
    S->Next = TmpCell;
}

BinTree StackPop(Stack S)
{
    Stack FirstCell;
    BinTree pos;
    if(S->Next == NULL) {
        printf("Stack Empty");
        return NULL;
    } else {
        FirstCell = S->Next;
        S->Next = FirstCell->Next;
        pos = FirstCell->Data;
        free(FirstCell);
        return pos;
    }
}

void PrintStack(Stack S)
{
    Stack head = S;
    while(head) {
        printf("%p ", head->Next);
        head = head->Next;
    }
    printf("\n");
}



BinTree Read()
{
    int N, data, count=0;
    char str[10];
    Stack S = CreateStack();
    BinTree head;
    BinTree BT = CreateBinTree(0);
    head = BT;
    scanf("%d\n", &N);
    scanf("Push %d\n", &BT->Data);
    StackPush(S, BT);
    count++;
    if(N) {
        while(!IsEmptyStack(S)||count<N) {      //是否堆栈为空,输入足够的结点
            scanf("%s", str);
            if(strcmp("Push", str) == 0) {      //区分Push和Pop
                scanf("%d", &data);
                if(BT->Left == NULL) {
                    InsertLeftLeafe(BT, data);
                    BT = BT->Left;
                    StackPush(S, BT);
                    count++;
                } else if(BT->Right==NULL) {
                    InsertRightLeafe(BT, data);
                    BT = BT->Right;
                    StackPush(S, BT);
                    count++;
                } else {
                    printf("can't go here\n");
                }
            } else {
                BT = StackPop(S);
            }
            // printf("head:");
            // PreOrderTraversal(head);
            // printf("\nstack:");
            // PrintStack(S);
        }
        return head;
    }
    return NULL;
}

void PostOrderTraversal(BinTree BST)
{
    int count = 0;
    if(BST == NULL)
        return;
    Stack S = CreateStack();
    BinTree Prev = NULL, Curr = NULL;
    StackPush(S, BST);
    while(!IsEmptyStack(S)) {
        Curr = S->Next->Data;
        if(Prev == NULL||Prev->Left == Curr || Prev->Right == Curr) {
            if(Curr->Left != NULL)
                StackPush(S, Curr->Left);
            else if(Curr->Right != NULL)
                StackPush(S, Curr->Right);
        } else if(Curr->Left == Prev) {
            if(Curr->Right != NULL)
                StackPush(S, Curr->Right);
        } else {
            if(!count) {
                printf("%d", Curr->Data);
                count++;
            } else {
                printf(" %d", Curr->Data);
            }
            StackPop(S);
        }
        Prev = Curr;
    }
}

int main()
{
    int N;
    BinTree BT;
    BT = Read();
    PostOrderTraversal(BT);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值