プロパティ
基本的な性質:バイナリツリー_ 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 \)
ために:最初の左部分木の枝を通過した後、ルートノードを通過し、最終的には右のサブツリーを横断します。
順序内での:\(DBEFAGHCI \)
オーダー後:最初の左部分木の枝を通過した後、右のサブツリーを横断し、最終的にルートノードを横断します。
シーケンスの後にシーケンス:\(DEFBHGICA \)
バイナリツリートラバーサルの実装
後順は、非再帰的な、それが一緒にスタック、左右のプッシュ順序(左の一次、右)、及び、スタックにこれらのノード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;
}