バイナリツリートラバーサル(私を突いてください)の記事では、バイナリ検索ツリーのトラバーサルが主に紹介されています。この記事では、バイナリ検索ツリーの検索について引き続き紹介します。
2番目の検索フォークツリーの検索には、主に、指定された要素ノードの検索、最大および最小の検索、および指定されたノードの先行ノードまたは後続ノードの検索が含まれます。以下に別途紹介します。
指定された要素を検索します
バイナリ検索フォークツリーで特定の値キーを検索するプロセスは、バイナリ検索と非常によく似ています。プロセスは次のとおりです。まず、キーワードキーがツリーのルートのキーと比較されます。キーがルートのキーよりも大きい場合、キーは次のようになります。右側のサブツリーを検索するか、ルートの左側のサブツリーを検索します。空のノードが見つかるか検出されるまで、このプロセスを繰り返します。次の図は、2つのノードのキーを見つけるプロセスを示しています。
検索プロセスによると、再帰的および非再帰的なコードの実装は次のとおりです。
//查找值为key的节点,递归版本
Node* bstree_search(BSTree root, Type key)
{
if (root==NULL || root->key==key)
return root;
if (key < root->key)
return bstree_search(root->left, key);
else
return bstree_search(root->right, key);
}
//查找值为key的节点,非递归版本
Node* iterative_bstree_search(BSTree root, Type key)
{
while ((root!=NULL) && (root->key!=key))
{
if (key < root->key)
root = root->left;
else
root = root->right;
}
return root;
}
最大値と最小値を見つける
バイナリ検索ツリーの性質に応じて、空でないバイナリ検索ツリーが最大値を見つけることは簡単に考えられます。プロセスは単純で、ルートノードから右側のサブツリーノードに再帰的に移動するだけで済みます。次の図に示すように、トラバースされたノードの右の子がNULLの場合、このノードはツリーの最大値になります。
同様に、最小値を見つけるプロセスも同様です。ルートノードから左側のサブツリーノードまで再帰的にトラバースします。トラバースされたノードの左の子がNULLの場合、このノードはツリーの最小値です。
最大値を見つけるためのコード実装を以下に示します。最小値も同様です。自分で最小値を見つけることを試みることができます。
//查找最大值
Node* bstree_maximum(BSTree root)
{
if (root == NULL)
return NULL;
while(root->right != NULL)
root = root->right;
return root;
}
先行ノードと後続ノードを検索する
ここで説明するノードの先行ノードと後続ノードは、順序どおりのトラバーサルシーケンス内の特定のノードの先行ノードと後続ノードを指します。詳細:バイナリ検索ツリーの場合、特定のノードxの先行ノードはキーよりも小さくなります。 [x]のすべてのキーワードの中で最大のノードであり、後続はkey [x]のすべてのキーワードの中で最小のノードです。
先行ステップを見つける:
(1)最初にノードxに左サブツリーがあるかどうかを判断します。左サブツリーがある場合、その左サブツリーの最大ノードはxの先行ノードです。
(2)左サブツリーがないが、ノードがその親ノードの右側にある場合子の場合、親ノードはノードの先行ノードです。
(3)左の子ツリーがないが、ノードがその親ノードの左の子である場合は、親ノードが見つかるまで、親ノードに沿ってツリーの上部を探す必要があります。ノードP、Pノードはその親ノードQの右の子であり、Qはこのノードの先行ノードです。
後続ノードを見つける手順:
(1)最初にノードxに正しいサブツリーがあるかどうかを判断します。正しいサブツリーがある場合は、その右側のサブツリーの最小ノードがxの先行ノードです。
(2)正しいサブツリーがないが、このノードがある場合親ノードの左の子である場合、親ノードはノードの後続ノードです。
(3)右の子ツリーがないが、ノードが親ノードの右の子である場合、ツリーまで親ノードをたどる必要があります。親ノードQの左の子であるノードPが見つかるまで上部を検索すると、Qがこのノードの後継になります。
3番目のケースでは、テキストが少し抽象的である可能性があります。図を使用してそれを示しましょう。たとえば、次の図は、ノード13の後継ノード15のプロセスを示しています。
先行ノード検索のコード実装を以下に示します。後続ノードも同様です。後続ノード検索コードの実装を自分で試すことができます。
//查找节点x的前驱节点Node* bstree_predecessor(Node *x)
{
/* 如果x存在左孩子,则"x的前驱结点"为
"以其左孩子为根的子树的最大结点"。*/
if (x->left != NULL)
return bstree_maximum(x->left);
// 如果x没有左孩子。则x有以下两种可能:
// (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
/* (02) x是"一个左孩子",则查找"x的最低的父结点,
并且该父结点要具有右孩子",找到的这个"最低的父结点"
就是"x的前驱结点"。*/
Node* y = x->parent;
while ((y!=NULL) && (x==y->left))
{
x = y;
y = y->parent;
}
return y;
}
推奨読書:
[福祉]自分で集めたオンラインブティックコースのビデオ共有(パート1 )
[システム設計] LRUキャッシュ
[データ構造とアルゴリズム]わかりやすいバイナリ検索ツリー
[データ構造とアルゴリズム]わかりやすいリンクリスト
[データ構造とアルゴリズム]ビットソーティングのわかりやすい説明
[C ++ノート] C ++ 11同時プログラミング(1)スレッドジャーニーの開始
[C ++ノート] C / C ++ポインターを使用する際の一般的な落とし穴
サーバーのバックグラウンドテクノロジースタックの知識の概要の共有に焦点を当てる
コミュニケーションと共通の進歩に注意を払うことを歓迎します
コーディング
コードファーマーには、テクノロジーを簡単にするためのわかりやすい技術記事を提供する正しい方法があります。