PAT甲级(Advanced Level)练习题——1004

Tree Traversals Again
给了一个模拟的二叉树非递归中序遍历push/pop序列,要求我们求出其后序遍历。

我的思路是这样的,先根据push/pop序列求出其先序遍历(即push的顺序)和中序遍历(即每次pop时候栈顶的值),再递归重建二叉树,最后再后序遍历即可。

#include 
#include 
#include 

using namespace std;

struct BTNode   // tree node
{
    int data;
    BTNode *lchild, *rchild;
};

BTNode *reBuildTree (int preOrder[], int inOrder[], int n)
{
    if(n <= 0) return NULL;      // 左右子树的节点为0,即递归结束时,返回空指针

    BTNode *root = new BTNode;
    root->data = preOrder[0];    // 前序遍历的第一个元素是根节点的值

    int i = 0;
    for(; ilchild = reBuildTree(preOrder+1, inOrder, i);  // 将数组名当指针使用
    root->rchild = reBuildTree(preOrder+1+i ,inOrder+i+1, n-i-1);
    return root;
}

void postorder(BTNode *root)
{
    if (root == NULL)
    {
        return;
    }
    postorder(root->lchild);
    postorder(root->rchild);
    cout << root->data << " ";
}

int main()
{
    freopen("input.txt", "r", stdin); //

    stack i_stack;
    stack pre_order, in_order;

    int s_number = 0;
    cin >> s_number;

    for (int i=0; i<2*s_number; i++) //记录先序遍历与中序遍历
    {
        string s_temp;
        cin >> s_temp;

        if (s_temp.at(1) == 'u')    // 字符串为"push"
        {
            int i_temp;
            cin >> i_temp;
            pre_order.push(i_temp); // 记录先序遍历
            i_stack.push(i_temp);       // 入栈
        }
        else
        {
            int i_temp = i_stack.top();
            i_stack.pop();              // 出栈
            in_order.push(i_temp);      // 记录中序遍历
        }
    }

    int *Pre_order  = new int[s_number];
    int *In_order  = new int[s_number];

    for (int i=s_number-1; i>=0; i--)    // 这里用数组比较方便,因为数组名可以当做指针使用,递归时可直接修改地址
    {
        Pre_order[i] = pre_order.top();
        In_order[i] = in_order.top();
        pre_order.pop();
        in_order.pop();
    }

    BTNode *BinaryTree = reBuildTree(Pre_order, In_order, s_number);
    postorder(BinaryTree);

    return 0;
}

// for (int i=num-1; i>=0; i--)
// for (int i=0; i

测试用例并没有问题,但是...在OJ上报错了,查看测试点发现测试数据给了许多重复值,如:

4
push 2
push 3
pop
push 1
pop
push 3
push 3
pop
pop
pop
push 4
pop

这就使得我在寻找根节点的位置这一步出错

后来参考了别人的代码

#include
#include
#include
 
using namespace std;
int n,cnt = 1;
char s[20];
vector out;
struct node {
    int val;
    struct node *left, *right;
};
node* buildTree()  // 直接重建二叉树,先左后右,左边会一直深入,直到left == NULL,再转向right
{
    if (cnt < 2 * n) {
        scanf("%s", s);
        cnt++;
        if (s[1] == 'u') {
            int v;
            node* temp = new node();  
            scanf("%d",&v);
            temp->val = v;
            temp->left = buildTree();
            temp->right = buildTree();
            return temp;
        }
        else {
            return NULL;
        }
    }
    return NULL;
}
void post(node* root) {
    if (root->left != NULL) {
        post(root->left);
    }
    if (root->right != NULL) {
        post(root->right);
    }
    out.push_back(root->val);
}
int main() {
 
    scanf("%d", &n);
    node *root = NULL;
    root = buildTree();
    post(root);
    printf("%d", out[0]);
    for (int i = 1; i < n; i++) {
        printf(" %d", out[i]);
    }
    return 0;
}

顺利通过~

你可能感兴趣的:(PAT甲级(Advanced Level)练习题——1004)