【PAT甲级 树的遍历 C++】1086 Tree Traversals Again (25 分)

第一次:测试点4错误
经过一两个小时的检查发现,是输入数据的方法错了,算法完全没错:

getline(cin, cmd);
int x = *cmd.rbegin() - '0'; // 呵呵,sb才会这么写,哈哈哈我是sb

后来想了一下,噢,原来结点数超过个位数时,上面这种输入方法就会完全错误,原来是这样啊,哈哈哈哈哈哈哈,***,wcnmlgb,我特么的这一两个小时郁闷了好久以为自己的算法有错,结果发现只是输入的错……顿时心态爆炸。

下次小心吧hhhhh

附上错误输入的代码:

# include <bits/stdc++.h>
using namespace std;

int N; // 结点个数

struct Node{
    
    
    int val;
    Node * lchild;
    Node * rchild;
    Node(int _val):val(_val), lchild(nullptr), rchild(nullptr){
    
    }
};

int cnt = 0;
void postorder(Node * root){
    
    
    if(root == NULL) return;

    postorder(root->lchild);
    postorder(root->rchild);
    cout << root->val;
    ++cnt == N ? cout << endl : cout << " ";
}

int main(){
    
    
    scanf("%d\n", &N);
    stack<Node *> S;
    Node * R = nullptr;
    Node * root = nullptr;
    for(int i = 0; i < 2*N ;++i){
    
    
        string cmd;
        getline(cin, cmd); // sb的输入方式
        if(cmd == "Pop"){
    
     // pop
            root = S.top();
            S.pop();
        }
        else{
    
     // push x
            int x = *cmd.rbegin() - '0'; // sb的转换方式
            if(root == nullptr){
    
    
                root = new Node(x);
                R = root;
            } else
            if(root->lchild == nullptr){
    
    
                root->lchild = new Node(x);
                root = root->lchild;
            } else
            if(root->rchild == nullptr){
    
    
                root->rchild = new Node(x);
                root = root->rchild;
            }
            S.push(root);
        }
    }
    postorder(R);
        
    return 0;
}

AC代码(自己的写法)

# include <bits/stdc++.h>
using namespace std;

int N; // 结点个数

struct Node{
    
    
    int val;
    Node * lchild;
    Node * rchild;
    Node(int _val):val(_val), lchild(nullptr), rchild(nullptr){
    
    }
};

int cnt = 0;
void postorder(Node * root){
    
    
    if(root == nullptr) return;

    postorder(root->lchild);
    postorder(root->rchild);
    cout << root->val;
    ++cnt == N ? cout << endl : cout << " ";
}

int main(){
    
    
    scanf("%d\n", &N);
    stack<Node *> S;
    Node * R = nullptr;    // 真的根
    Node * root = nullptr; // 建树的根
    for(int i = 0; i < 2*N ;++i){
    
    
        string cmd;
        cin >> cmd;
        if(cmd == "Pop"){
    
     // pop
            root = S.top();
            S.pop();
        }
        else{
    
     // push x
            int x;
            cin >> x;
            if(root == nullptr){
    
    
                root = new Node(x);
                R = root;
            } else{
    
    
                if(root->lchild == nullptr){
    
     // 前一步操作是Push时,那么当前root的左子树必定为空,那么这一步Push就是插入左子树
                    root->lchild = new Node(x);
                    root = root->lchild;
                } else // 前一步操作是Pop时,那么当前root的左子树必定不为空,而右子树一定为空,那么这一步Push就是插入右子树
                if(root->rchild == nullptr){
    
    
                    root->rchild = new Node(x);
                    root = root->rchild;
                }
            }
            S.push(root);
        }
    }
    postorder(R);
        
    return 0;
}

AC代码(算法笔记的方法)

# include <bits/stdc++.h>
using namespace std;

struct Node{
    
    
    int l, r;
    Node():l(-1), r(-1){
    
    }
}node[31];

// Push是前序遍历,Pop是中序遍历
int N;
vector<int> pre, in;
vector<int> post;

// 根据树的前序和中序遍历序列建树
// 1 2 3 4 5 6 
// 3 2 4 1 6 5 
int creatTree(int preL, int preR, int inL, int inR){
    
    
    if(preL > preR) return -1;

    int root = pre[preL];

    int k;
    for(int i = inL;i <= inR;++i)
        if(in[i] == root)
            k = i;

    int numleft = k - inL;
    node[root].l = creatTree(preL+1, preL+numleft, inL, k-1);
    node[root].r = creatTree(preL+numleft+1, preR, k+1, inR);

    return root;
}

int cnt = 0;
void postTraverse(int root){
    
    
    if(root == -1) return;
    
    postTraverse(node[root].l);
    postTraverse(node[root].r);
    cout << root;
    ++cnt == N ? cout << endl : cout << " ";
}

int main() {
    
    
    scanf("%d\n", &N);
    stack<int> S;
    for(int i = 0;i < 2*N;++i){
    
    
        string cmd;
        cin >> cmd;
        if(cmd == "Push"){
    
    
            int x;
            cin >> x;
            pre.push_back(x);
            S.push(x);
        }
        else{
    
    
            in.push_back(S.top());
            S.pop();
        }
    }
    int R = creatTree(0, N-1, 0, N-1);
    postTraverse(R);

    return 0;
}

参考别人的:

# include <bits/stdc++.h>
using namespace std;

int N; // 结点个数

struct Node{
    
    
    int lchild;
    int rchild;
    Node():lchild(-1), rchild(-1){
    
    }
}node[31];

int cnt = 0;
void postorder(int root){
    
    
    if(root == -1) return;

    postorder(node[root].lchild);
    postorder(node[root].rchild);
    cout << root;
    ++cnt == N ? cout << endl : cout << " ";
}

int main(){
    
    
    scanf("%d\n", &N);
    stack<int> S;
    int R = 0; // 真的根
    int r = 0; // 变化的根
    int precmd;
    for(int i = 0; i < 2*N ;++i){
    
    
        string cmd;
        cin >> cmd;
        if(cmd == "Pop"){
    
     // pop
            r = S.top();
            S.pop();
            precmd = 0;
        }
        else{
    
     // push x
            int p;
            cin >> p;
            S.push(p);
            if(r == 0){
    
    
                R = p;
            } else{
    
    
                if(precmd == 1){
    
     // 前一步操作是Push时,那么这一步Push就是插入左子树
                    node[r].lchild = p;
                }
                if(precmd == 0){
    
     // 前一步操作是Pop时,那么这一步Push就是插入左子树
                    node[r].rchild = p;
                }
            }
            precmd = 1;
            r = p;
        }
    }
    postorder(R);
        
    return 0;
}

猜你喜欢

转载自blog.csdn.net/MYMarcoreus/article/details/113880554
今日推荐