PTA L2-035完全な二分木トラバーサル(ツリートラバーサル)

L2-035完全な二分木のシーケンストラバーサル(25ポイント)

二分木。各層のノード数が最大に達すると、二分木は完全な二分木になります。深さがDノードとNノードのバイナリツリーの場合、そのノードが同じ深さの完全なバイナリツリーのシーケンストラバーサルの最初のNノードに対応する場合、そのようなツリーは完全なバイナリツリーです。

完全な二分木のポストオーダートラバーサルを前提として、ツリーのトラバーサルの結果を示してください。

入力フォーマット:

ツリー内のノード数である正の整数N(≤30)を最初の行に入力します。2行目は、100を超えないN個の正の整数であるポストオーダートラバーサルシーケンスを示しています。同じ行のすべての数字はスペースで区切られます。

出力フォーマット:

ツリーの走査シーケンスを1行で出力します。すべての数字は1スペースで区切られ、行の最初と最後に余分なスペースがあってはなりません。

入力サンプル:

8
91 71 2 34 10 15 55 18

サンプル出力:

18 34 55 71 2 10 15 91

問題解決

これはまだバイナリツリートラバーサルです。ここでは、出力レイヤーシーケンストラバーサルにはbfsが必要であり、タイトルはポストオーダートラバーサル(dfs)で指定されます。したがって、レイヤーシーケンストラバーサルを見つけるためにツリーを構築する必要があります。ツリーを構築することは、左右のサブツリーのノードを見つけることです。数、この質問は、完全な二分木の性質を使用する必要があります。
ここで、完全な二分木に残っているサブツリーの数を見つけるために、完全な二分木TにN個のノードがあるとします。

  • N左+ N右= N-1

最初は、左側のサブツリーのノード数は0です。次に、
+ 1、+ 2、+ 4、+ 8、+ 16、...、+、...
ルールを見つけて使用し、次のように追加し続けます。すべてのサブツリーノードが追加され、カウント左側のサブツリー内のノードの数を見つけ、dfsを使用してトラバースしてツリーを構築し、最後にbfsを使用してツリーをトラバースして階層トラバーサルを取得します。

コード

#include <algorithm>  //L2-035 完全二叉树的层序遍历 (25分)
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

vector<int> back, num;

typedef struct TNode {
    
    
    TNode *left, *right;
    int value;
} * Tree;

Tree dfs(int l, int r, Tree T) {
    
      //建树
    if (l > r) return NULL;

    if (!T) T = new TNode();
    T->value = back[r];

    int A = 0;    //记录左子树长度
    int len = 1;  //单行的大小
    bool isLeft = true;
    int cnt = 0;
    for (int i = l; i < r; i++) {
    
    
        cnt++;
        if (isLeft) A++;

        if (cnt == len) {
    
      //记录完其中一条子树的一行时
            cnt = 0;
            if (!isLeft) len <<= 1;  //如果记录一行最后一个
            isLeft = !isLeft;
        }
    }

    T->left = dfs(l, l + A - 1, T->left);
    T->right = dfs(l + A, r - 1, T->right);
    return T;
}

void bfs(Tree T) {
    
    
    queue<Tree> q;
    q.push(T);
    while (!q.empty()) {
    
    
        Tree T = q.front();
        num.push_back(T->value);
        q.pop();

        if (T->left) q.push(T->left);
        if (T->right) q.push(T->right);
    }
}

int main() {
    
    
    int N;
    cin >> N;
    back.resize(N);
    for (int i = 0; i < N; i++) cin >> back[i];

    Tree T = dfs(0, back.size() - 1, NULL);
    bfs(T);

    for (int i = 0; i < num.size(); i++) {
    
    
        if (i) cout << " ";
        cout << num[i];
    }
    cout << endl;

    system("pause");
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_45349225/article/details/111168323