どのように、我々はバランスの取れた二分木を得ますか?
9994 ワード
バイナリツリー
エー
binary tree
, 名前が示すようにtree
各ノードが2つの子ノードを持つ場合.バイナリツリーは空であり、ツリー内のゼロノードを意味する.クールなことbinary trees
は再帰的な構造である.これは、すべてのツリーに対して順番にそれを適用することにより、ツリー全体にルールを適用することができます.バイナリツリーを定義するには、2つのデータ構造が必要です.一つはルートノードを追跡する全体的なバイナリツリー構造である.もう一方は、左右の部分木を追跡するノード構造である.
class binaryTree {
public:
node * root; //a pointer to the root
};
では、ノード構造を定義して、左右の子ノードの両方を追跡し、データを格納します.この場合、キーを呼び出します.class node {
public:
node * left; //a pointer to the root of the left subtree
node * right; //a pointer to the root of the right subtree
int key;
};
ここでは、キーデータ型がinteger
, ちょうど物事をシンプルに保つ.しかし、それは注意しなければなりませんkey
タイプは、比較演算子、すなわち、<<>>>>、<= ,=を許すデータ構造です.このレッスンは、もともと2007年に出版されましたhttps://algodaily.com , 私は技術的なインタビューコースを維持し、野心的な開発者のために考える作品を書く.
バイナリ検索ツリー
バイナリ検索ツリー
BST
バイナリの木の特別な場合です.そして、それは木の中で重要な値の配置に加えられた制約を持ちます.簡単に言えば、bstは以下の規則で定義されます:バランスBST
エー
balanced BST
左と右のサブツリーの高さの違いが1つ以下であるBSTです1
). これらの例題は明確にする必要があります.ハウツーとスタイル
BSTに対する平衡アルゴリズムが存在する.
red black trees
or AVL trees
. これらの構造において、BSTの範囲内で鍵の挿入および削除は、木が平衡のままであるような方法で行われる.しかし、与えられた
unbalanced
ツリーは、効率的な方法でバランスの取れたツリーに変換する方法ですか?配列を使うことで、とてもシンプルで効率的なアルゴリズムがあります.2つのステップがあります.ステップ1:順横断
ステップ2:バランスBSTを作成
彼らを探検しましょう.バランスのとれたBSTを効率的に作成するための擬似コードは再帰的であり、基底ケースと再帰的ケースは以下のようになります.
ベースケース:
null
ポインタと停止.再帰的な場合:
build
メソッド.build
配列の左側の半分に.ルートノードの左の子は、この再帰的な呼び出しによって返されるポインタです.build
配列の右半分.ルートノードの右の子は、この再帰呼び出しによって返されるポインタです.あなたは、配列の真ん中を得る方法を不思議に思うかもしれません.単純式
(size/2)
中央の項目のインデックスを返します.もちろん、配列のインデックスが0
.以前の擬似コードがどのように機能するかを見てみましょう.我々はいくつかの簡単なシナリオを取るし、より複雑なものを構築します.
Array : [ 30 ]
最初に、1つの要素だけで以下の配列を見ます.
30
).array : [ 31 , 37 , 38 ]
それではサイズ3の配列を見ましょう.
array :[ 10 , 11 ]
私たちは今、2つの要素を持つ偶数サイズの配列のために行きましょう.
array : [ 10 , 11 , 17 , 19 ]
この例を、4つの要素を持つ偶数サイズの配列に拡張できます.
array : [ 10 , 11 , 17 , 19 , 30 , 31 , 37 , 38 ]
つの要素を持つ偶数サイズの配列.
今、我々は、バランスの仕組みを理解し、我々は楽しい部分を行うことができます、コーディングです.ここでは、再帰的なルーチンです
build
我々が以前定義したこと.以下のコードは、上記のヘルパー再帰関数
build
:void build(int *arr, int size, binaryTree &tree) {
tree.root = build(arr, 0, size-1);
}
// build returns a pointer to the root node of the sub-tree
// lower is the lower index of the array
// upper is the upper index of the array
node * build(int * arr, int lower, int upper) {
int size = upper - lower + 1;
// cout << size; //uncomment in case you want to see how it's working
// base case: array of size zero
if (size <= 0)
return NULL;
// recursive case
int middle = size / 2 + lower;
// make sure you add the offset of lower
// cout << arr[middle] << " "; //uncomment in case you want to see how it's working
node * subtreeRoot = new node;
subtreeRoot - > key = arr[middle];
subtreeRoot - > left = build(arr, lower, middle - 1);
subtreeRoot - > right = build(arr, middle + 1, upper);
return subtreeRoot;
}
上記のコードを試してみる前に、常に紙とペンで座って、コードの乾いた実行を何回か行います.前のコードは、O(N)
, どこN
はツリー内のキーの数です.Inorder traversal
必要O(N)
時間.配列の各要素に一度だけアクセスしているのでbuild
方法は、また、このように時間の複雑さを有するO(N)
.このレッスンは、もともと2007年に出版されましたhttps://algodaily.com , 私は技術的なインタビューコースを維持し、野心的な開発者のために考える作品を書く.
Reference
この問題について(どのように、我々はバランスの取れた二分木を得ますか?), 我々は、より多くの情報をここで見つけました https://dev.to/jacobjzhang/how-do-we-get-a-balanced-binary-tree-259eテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol