二分探索木の性質:
1、左側のサブツリー上のすべてのノードの値は、ルートノードの値以下です。
2、右側のサブツリー上のすべてのノードの値は、そのルートノードの値以上です。
最大ヒープ特性:
1、2つのサブツリーのすべてのノードの値は、ルートノードの値以下です。
1.前任者と後任者:
バイナリツリーでの実行中間オーダートラバーサル(レイヤー順ではない)、トラバーサル後の順序、現在のノードの前のノードはこのノードの先行ノードであり、現在のノードの次のノードはこのノードの後続ノードです。
1.1二分探索木の場合:
ノードx
先行ノード:x.key
最大のキーノード(15前駆体前駆体4,7 6,17 6)よりも小さい;
ノードx
後続ノード:x.key
最小のキーノード(6 7、7の後継、9の後継、13の後継15);
後継の疑似コード:
int TreeSuccessor(node x)
{
if(x.right != NULL) return Tree_minmum(x.right);
y = x.p;
while(y!=NULL && x ==y.right){
//若x为右节点,则后继为最低的祖先且其左孩子也是祖先(13的后继15)
x = y;
y = y.p;
}
return y; //若x为左节点,则返回父节点
}
2.挿入と削除:
2.1。挿入:
新しく挿入されたノードは常にリーフノードですしたがって、見つかった適切な位置は空であり、空のノードの親ノードが挿入のために記録されます。
擬似コードを挿入:
void TreeInsert(Tree T, node z)
{
y = NULL;
x = T.root; //x用于找位置指导为空即找到,y为x的父节点
while(x != NULL){
y = x;
if(z.key<x.key){
x = x.left;
}else{
x = x.right;
}
}
z.p = y;
if(y == NULL){
// 树为空
T.root = z;
}
else if (z.key<y.key){
y.left = z;
}
else{
y.right = z;
}
}
13は15の下に挿入されます:
2.2。削除:
3つの状況があります:
a)単純な状況:子が1つだけあるか、子がない場合、別の子またはNULLに置き換えますz
b)複雑な状況: 2人の子供がいて、適切な子供が後継者であるかどうかにかかわらず、2つの状況に分けられます。
目的:z
後継が後継ですy
(z
最小値がより大きい)
b1)正しい子は彼の後継者です:後継者にy
置き換えるz
右の子は後続(彼の最小値よりも大きい)であり、右の子に左の子がないことを示します。
b2)正しい子は彼の後継者ではない:後継者とy
場所で、子供の権利y
、y
代わりにz
偽のコード:
// v数代替u树的小函数
void Transplant(Tree T, node u,node v)
{
if(u.p = NULL) t.root = v;
else if(u = u.p.left) u.p.left = v;
else u.p.right = v;
if(v != NULL) v.p = u.p;
}
ノードの削除機能:
**リファレンス:**アルゴリズムの概要:セクション12.2クエリのバイナリ検索ツリーとセクション12.3の挿入と削除
総括する:
1.二分探索木の性質:左側のサブツリーのすべてのノードはルートノードよりも小さい(右側のサブツリーはより大きい)。
2.先行および後続は、順序どおりのトラバース後のノードを指します。
3.二分探索ツリーの後続(先行)は、ノードより大きい(より小さい)ノードの最小(最大)ノードです。
4.バイナリ検索ツリーに新しく挿入されたノードは常にルートノードから始まり、ルートノードから始まり、空のリーフノードと比較されます。(これは、ヒープにノードを挿入することとは異なります。ヒープは最初にヒープの最後に配置され、次にルートノードと比較して、大きい場合は上に移動します)。
5.バイナリ検索ツリーから削除します。子が1つしかない場合、または子がない場合は、削除したノードを別の子またはNULL z
に置き換えます。子が2つある場合は、削除したノードを後続ノードに置き換えます。
6.二分探索木での基本操作(挿入、削除、先行、後続、最大、最小)の時間は、期待される高さがlg(n)であるため、木の高さに比例します。平均稼働時間lg(n)です。
7.赤と黒の木最悪の実行時間lg(n)です。