03-树3 Tree Traversals Again (25 分)------C语言

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

        这题其实我刚开始是真的不会,是看了其他大佬的代码才知道咋回事儿,原来是前序+中序-->后序的思路。

        想想前序学习的时候,我们是咋写代码的,是不是入栈一个出栈一个,那么题目中只要是“push”,那就是在入栈,而前序是入一个出一个,先入先出,那按照顺序把“push”后面的数字一个一个正序放到数组中,输出的时候也正序输出不就是前序序列了吗

        而要找到中序序列可太简单了,因为题目输入的就是中序序列,照着做就行,建立一个栈,按照题目输入照做就行。

        那怎么得到后序呢?哎,前序是(根、左、右),后序是(左、右、根),头和屁股最好找,那在前序找到根,把它放到后序的屁股那儿就行。

        这里我们要使用递归方法,也就是说把一个大序列分成几个小序列,也就是说我们要找到每个小序列在哪儿,怎么表示。想想中序,如果我们从前序知道了根节点,在中序中找到这个根节点,是不是这个根节点的左边就是左子树(一个小序列出来了),右边的就是右子树(又一个小序列),这样循环往复,又从左子树分成两个左右子树,右子树分成两个左右子树.........一个又一个的子序列就出来了。

        总结一下,从前序找到根节点,放到后序屁股,要想知道后序屁股在那儿,得知道这个子序的长度,长度就从中序中获得,从中序中找到根节点,左右既是两个子序列的长度。

因为代码是我参照其它大佬写的,很相似,我就不在上面写相应解说了,放上我的代码,然后我贴个大佬代码的链接,上面写的很详细。

https://blog.youkuaiyun.com/qq_43590403/article/details/93730467(大佬原代码链接,可以看看执行思路)

//03-树3 Tree Traversals Again
#include<stdio.h>
#include<stack>
#define MaxTree 35
using namespace std;

int pre[MaxTree], mid[MaxTree], post[MaxTree];
void GetPostroot(int PreL, int MidL, int LastL, int length);

int main()
{
    int N=0, i=0, j=0, k=0, number=0;
    char str[8];
    stack <int> s;
    scanf("%d", &N);
    for(i=0;i<2*N;i++){
        scanf("%s", str);
        if(str[1]=='u'){
            scanf("%d", &number);
            pre[j++]=number;
            s.push(number);
        }
        else{
            mid[k++]=s.top();
            s.pop();
        }
    }
    GetPostroot(0, 0, 0, N);
    for(i=0;i<N;i++){
        printf("%d", post[i]);
        if(i!=N-1) printf(" ");
    }
    
    return 0;
}

void GetPostroot(int PreL, int MidL, int LastL, int length)
{
    if(length==0) return;
    if(length==1){
        post[LastL]=pre[PreL];
        return; 
    }
    int root=pre[PreL];
    post[LastL+length-1]=root;
    int i=0;
    for(i=0;i<length;i++){
        if(mid[MidL+i]==root) break;
    }
    int L=i;
    int R=length-i-1;
    GetPostroot(PreL+1, MidL, LastL, L);
    GetPostroot(PreL+1+L, MidL+L+1, LastL+L, R);
}

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值