【華科考研機試題】二叉樹遍歷(遞歸版 詳細註釋)

題意

輸入前序遍歷序列字符串a,中序遍歷字符串b,輸出後序遍歷字符串。node

解題思路

1.已知前序遍歷,中序遍歷求後序遍歷,常規作法是創建一棵樹。
2.用手算的話很簡單,將字符串a遍歷一遍,依次插入到樹中。ios

插入關鍵代碼以下

for(a[i] in a){
    //插入a[i]
    int flag = 1;// 標誌位爲1表示a[i]還未插入
    設置p指針指向根結點 
    while(flag){
        if(a[i]比p指向的結點的字母 在b字符串 中的索引小){
            if(p->left爲空){
                將a[i]插入到p->left位置 
                flag = 0; //a[i]插入完成,跳出循環 
            }else{
                p指向p->left 
            }
        } else{//a[i]比p指向的結點的字母 在b字符串 中的索引大 
            if(p->right爲空){
                將a[i]插入到p->right位置 
                flag = 0; //a[i]插入完成,跳出循環 
            }else{
                p指向p->right 
            }
        }
    } 
}

代碼

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

struct node{
    char val;
    node* left;
    node* right;
};
node* root;
string a,b;

//若是c在x左邊,返回1 
bool InLeft(char x, char c){
    for(int i = 0;b[i]; ++i){
        if(b[i] == x){
            return 0;
        }
        if(b[i] == c){
            return 1;
        }
    }
    return 0; //此句理解起來可忽略,刪掉牛客網編譯器會報錯。 
}

void insert(char c){
    node* p = root;
    //flag爲1表示c未插入到樹中 
    int flag = 1;
    //爲即將插入的結點申請空間 
    node* newNode = (node*)malloc(sizeof(node));
    newNode->left = NULL;
    newNode->right = NULL;
    newNode->val = c;
    
    while(flag){
        //若是c 在當前結點p的左邊(在b中的相對位置) 
        if(InLeft(p->val, c)){
            //若是當前結點p的左子樹不爲空 
            if(p->left){
                p = p->left;
            }else{
                p->left = newNode;
                flag = 0;
            }
        }else{
            if(p->right){
                p = p->right;
            }else{
                p->right = newNode;
                flag = 0;
            }
        }
    }
}


//後續遍歷的遞歸(偷懶)寫法,非遞歸得用棧 
void dfs(node* root){
    if(!root) return;
    if(root->left) dfs(root->left);
    if(root->right) dfs(root->right);
    cout << root->val;
}

int main() {
    ios::sync_with_stdio(false);
    while(cin >> a >> b){
        root = (node*)malloc(sizeof(node)); 
        //若是a字符串不爲空,將第一個字母設置爲根結點字母 
        if(a[0]) root->val = a[0], root->left = NULL, root->right = NULL;
        //遍歷a字符串後續字母,依次插入到樹中 
        for(int i = 1;a[i]; ++i){
            insert(a[i]);
        }
        //後序遍歷輸出樹 
        dfs(root);
        cout << endl;
    }
    return 0;
}
相關文章
相關標籤/搜索