PAT 1127 ZigZagging on a Tree

题目是给出树的中序遍历和后序遍历,求层序遍历,层序遍历输出时一行从左向右输出,下一行从右向左输出,形成Z字层序输出。
这一题想了半天,也只能通过建立二叉树,然后再进行层序遍历输出。
建立二叉树时,花了挺久的时间,主要是确定左右的界限以及什么时候停止,用后序遍历在中序遍历上找到中序遍历上以当前节点为根的子树的范围。
输出时,用了两个队列和两个栈,用一个队列将同一层的元素输入输出,从左向右输出时将元素压入另个队列中输出,然后将子元素压入主队列,从右向左输出时将元素压入栈后输出,然后再压入另一个栈把顺序调回来后将子元素压入主队列。
(用时:3:15:57.35)

#include <bits/stdc++.h>
using namespace std;
struct BiTree {
    int value;
    BiTree *left,*right;
}*BTree;
BiTree* GetTree(int inOrder[],int postOrder[],int index,BiTree *root,int left,int right)
{
    int lIndex = -1;
    int rIndex = -1;
    int i=0;
    if(left >= right) {
        return NULL;
    }
    for( i=left; i<right; i++) {
        if(inOrder[i]==postOrder[index]) {
            lIndex = index-(right-i);
            if(i==left) {
                left++;
            }
            break;
        }
    }
    root = (BiTree *)malloc(sizeof(BiTree));
    root->value = postOrder[index];
    root->right = NULL;
    root->left = NULL;
//printf("%d\n",postOrder[index]);
//   printf("index=%d left=%d right=%d lIndex=%d rIndex=%d i=%d  value=%d\n",index,left,right,lIndex,rIndex,i,root->value);
    if(lIndex !=-1) {
        root->left = GetTree(inOrder,postOrder,lIndex, root->left,left,i);
    }
    rIndex = index-1;
//   printf("index=%d left=%d right=%d lIndex=%d rIndex=%d  i=%d  \n",index,left,right,lIndex,rIndex,i);
    if(i+1<right&&rIndex !=-1 )  {
        root->right = GetTree(inOrder,postOrder,rIndex, root->right,i+1,right);
    }

    return root;
}
int main()
{
    int n;
    scanf("%d",&n);
    int inOrder[n];
    int postOrder[n];
    for(int i=0; i<n; i++) {
        scanf("%d",&inOrder[i]);
    }

    for(int i=0; i<n; i++) {
        scanf("%d",&postOrder[i]);
    }

    BiTree *root;
    root = GetTree(inOrder,postOrder,n-1, root,0,n);
    queue<BiTree*> que,que1;
    stack<BiTree*> sta,sta1;
    int left = 0;
    que.push(root);
    int first = 1;
    while(!que.empty()) {
        BiTree *p = que.front();
        que.pop();
        if(left) {
            if(p!=NULL) {
                que1.push(p);
            }
            if(que.empty()) {
                while(!que1.empty()) {
                    p = que1.front();
                    que1.pop();
                    printf(" %d",p->value);
                    if(p->left!=NULL) {
                        que.push(p->left);
                    }
                    if(p->right!=NULL) {
                        que.push(p->right);
                    }
                }
                left = 0;
            }
        } else {
            if(p!=NULL) {
                sta.push(p);
            }
            if(que.empty()) {
                while(!sta.empty()) {
                    p = sta.top();
                    sta1.push(p);
                    sta.pop();
                    if(first) {
                        printf("%d",p->value);
                        first = 0;
                    } else {
                        printf(" %d",p->value);
                    }
                }

                while(!sta1.empty()) {
                    p = sta1.top();
                    sta1.pop();
                    if(p->left!=NULL) {
                        que.push(p->left);
                    }
                    if(p->right!=NULL) {
                        que.push(p->right);
                    }
                }
                left = 1;
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值