バイナリツリーの一部1--ツリーデータ構造

プロパティ

基本的な性質:バイナリツリー_ Baiduの百科事典

ノードの層の数に関連する深さ(高さ)に二分木、材料指定されたルートの一部\(0 \)層、およびいくつかの第一の所定のルート\(1 \)層。

本明細書に全て「言語データ構造-C版」(ヤンウェイミン、ウーWeimin盤)優先:高さと深さ、同じ概念のを、第1の層1のルートノードは、ツリー、いくつかの層の合計の高さを見ることです。\(H \)までの完全なバイナリツリーは、(2 ^ {N} -1 \ \) ノードを、\(K \)のためにアップ層(2 ^ {K-1 \ } \) ノード。含む\(N- \)完全二分木ノード、高\(ログ(N)+ 1 \) 次丸め。

完全二叉树:

最初の要素の下にラベルされた場合は、\(1 \) その後、最初の\(K \)の左の子要素\(2 * k個\) 右の子がさ(2 * K + 1 \)を\、親である(K / 2 \)\最後のノードの丸めは、親である\(長さ/ 2 \)下丸め。

最初の要素の下で標準である場合(0 \)\、最初の\(K \)の左の子要素\(2 * K + 1 \) 右の子は、(2 * K + 2 \)を\します、親ノードは、- (1)/(K \ 2 \)を親ノードが最後である、丸め下\(長さ/ 2 \)マイナス1に丸めた後。

バイナリツリートラバーサルシーケンスの先行後続ノードは、時間、リア及びノードの正面を表します。

\(H \)完全二分木、するまで(2 ^ {H} -1 \ \) ノード。

ノードがある\(N- \)完全二分木、高さ\(ログ(N-)\)

バイナリツリートラバーサル

「中および後に、前に」を示している3つの方法が順トラバーサルでのバイナリツリートラバーサルは、最初の後に存在するルートノードのトラバーサル順序を

最初の注文:そのブランチの最初の横断ルートは、最終的に右のサブツリーを横断し、左のサブツリーをトラバース。

予約限定シーケンス:\(ABDFECGHI \)

IMG

ために:最初の左部分木の枝を通過した後、ルートノードを通過し、最終的には右のサブツリーを横断します。

順序内での:\(DBEFAGHCI \)

IMG

オーダー後:最初の左部分木の枝を通過した後、右のサブツリーを横断し、最終的にルートノードを横断します。

シーケンスの後にシーケンス:\(DEFBHGICA \)

IMG

バイナリツリートラバーサルの実装

後順は、非再帰的な、それが一緒にスタック、左右のプッシュ順序(左の一次、右)、及び、スタックにこれらのノードBを堆積するために、そして最終的にスタックにアクセスすると、2つのスタックA、Bを借り。

//先序
void preorderUnRecur(BTree T) {
    stack<BTree>s;
    s.push(T);
    while (!s.empty()) {
        T = s.top();
        s.pop();
        cout << T->data << " ";
        if (T->Right)
            s.push(T->Right);
        if (T->Left)
            s.push(T->Left);
    }
    cout << endl;
}

//中序
void inorderUnRecur(BTree T) {
    if (!T)return;
    stack<BTree>s;
        while (!s.empty() || T) {
            if (T) {
                s.push(T);
                T = T->Left;
            }
            else {
                T = s.top(); s.pop();
                cout << T->data << " ";
                T = T->Right;
            }
        }
    cout << endl;
}

//后序

void postorderUnRecur(BTree T) {
    if (!T)return;
    stack<BTree>s1,s2;
    s1.push(T);
        while (!s1.empty()) {
            T = s1.top(); s1.pop();
            s2.push(T);
            if (T->Left)s1.push(T->Left);
            if (T->Right)s1.push(T->Right);
    }
        while (!s2.empty()) {
            cout << s2.top()->data << " ";
            s2.pop();
        }
    cout << endl;
}

再帰、それに比べては比較的簡単です:

void Inorder(BTree t) {
    if (!t)return;
    Inorder(t->Left);
    cout << t->data << " ";
    Inorder(t->Right);
}
void Preorder(BTree t) {
    if (!t)return;
    cout << t->data << " ";
    Preorder(t->Left);
    Preorder(t->Right);
}
void Postorder(BTree t) {
    if (!t)return;
    Postorder(t->Left);
    Postorder(t->Right);
    cout << t->data << " ";
}

バイナリツリーの構築

  バイナリツリーの確立は、一般的に2つの方法があります。

(1)特別な値(例えば0、#)を有するアレイ状、またはノードの順序に従って入力は、現在位置がノードではないことを示しています。しかし、これは常にそのようなノードの値が0、#のASCII値であるとして、競合になります。私は書いていません。

(2)2つの配列は配列与えられた配列を含みます。以下は、バイナリツリーを作成するために、プリアンブル、時系列に与えられます。

含まれる配列によってシーケンスでは、2つの配列が唯一のバイナリツリーを導入することができる(唯一の前に、バイナリツリーを作成するためのシーケンスの後に固有のものではありません)。

typedef struct BTNode
{
    int data;
    struct BTNode* Left;
    struct BTNode* Right;
}*BTree;

void PreAndInToPost(int* pre, int* in, int length) {
    if (length == 0) return;
    int rootIndex;
    BTree BT = new BTNode;
    BT->data = *pre;
    for (rootIndex = 0; in[rootIndex] != *pre; rootIndex++);
    PreAndInToPost(pre + 1, in, rootIndex);
    PreAndInToPost(pre + rootIndex + 1, in + rootIndex + 1, length - (rootIndex + 1));
    cout << BT->data << " ";
}

void PostAndInToPre(int* in, int* post, int length) {
    if (length == 0) return;
    int rootIndex;
    BTree BT = new BTNode;
    BT->data = *(post + length - 1);
    for (rootIndex = length - 1; in[rootIndex] != *(post + length - 1); rootIndex--);
    cout << BT->data << " ";
    PostAndInToPre(in, post, rootIndex);
    PostAndInToPre(in + rootIndex + 1, post + rootIndex, length - (rootIndex + 1));
}

完全なテストコードを次のように:

#include <iostream>
using namespace std;

typedef char ElemType;

typedef struct BTNode
{
    ElemType data;
    struct BTNode* Left;
    struct BTNode* Right;
}*BTree;

BTree creat_tree_from_pre_inorder(ElemType* pre, ElemType* in, int length) {
    if (length == 0) return NULL;
    int rootIndex;
    BTree BT = new BTNode;
    //将当前根节点入树
    BT->data = *pre;
    for (rootIndex = 0; in[rootIndex] != *pre; rootIndex++);
    BT->Left = creat_tree_from_pre_inorder(pre + 1, in, rootIndex);
    BT->Right = creat_tree_from_pre_inorder(pre + rootIndex + 1, in + rootIndex + 1, length - (rootIndex + 1));
    return BT;
}
BTree creat_tree_from_post_inorder(ElemType* in, ElemType* post, int length) {
    if (length == 0) return NULL;
    int rootIndex;
    BTree BT = new BTNode;
    //将当前根节点入树
    BT->data = *(post + length - 1);
    for (rootIndex = length - 1; in[rootIndex] != *(post + length - 1); rootIndex--);
    BT->Left = creat_tree_from_post_inorder(in, post, rootIndex);
    BT->Right = creat_tree_from_post_inorder(in + rootIndex + 1, post + rootIndex/*删掉post的最后一个*/, length - (rootIndex + 1));

    return BT;
}


void Inorder(BTree BT) {
    if (!BT)return;
    Inorder(BT->Left);
    cout << BT->data << " ";
    Inorder(BT->Right);
}
void Preorder(BTree BT) {
    if (!BT)return;
    cout << BT->data << " ";
    Preorder(BT->Left);
    Preorder(BT->Right);
}
void Postorder(BTree BT) {
    if (!BT)return;
    Postorder(BT->Left);
    Postorder(BT->Right);
    cout << BT->data << " ";
}

int main() {
    char pre[] = "ABDGHCEIF";
    char in[] = "GDHBAEICF";
    char post[] = "GHDBIEFCA";
    BTree T1 = creat_tree_from_pre_inorder(pre, in, strlen(in));
    BTree T2 = creat_tree_from_post_inorder(in, post, strlen(in));
    Postorder(T1);
    cout << endl;
    Preorder(T1);
    cout << endl;
    return 0;
}

関連小さなアルゴリズム

バイナリツリーの深さを取得します。

int height(BTree T) {
    if (T == NULL)
        return 0;
    int left = height(T->Left);
    int right = height(T->Right);
    return left >= right ? left + 1 : right + 1;
}

おすすめ

転載: www.cnblogs.com/czc1999/p/11768769.html