線形テーブル検索は静的検索です。線形テーブルで動的検索を実行するには、次の問題があります:
順序付けられていないシーケンステーブルでの動的検索、単純な挿入操作、ただし検索の複雑度が高い。
順序付けされたシーケンステーブルでの動的検索、時間の複雑さが良いですが、挿入時間高の複雑見つけ
単一のリスト上のダイナミック・ルックアップ、単に操作のインサートが、高い操作の複雑さのため外観
:ソリューション、バイナリツリーデータ構造の使用、動的な検索
バイナリ・ソートツリー(バイナリ検索ツリー)
バイナリソートツリー(バイナリ検索ツリーとも呼ばれます):空のバイナリツリーまたは次のプロパティを持つバイナリツリー:(
1)左側のサブツリーが空でない場合、左側のサブツリーのすべてのノードルートノードの値よりも小さい;
right右側のサブツリーが空でない場合、右側のサブツリー上のすべてのノードの値はルートノードの値よりも大きい;
leftその左側および右側のサブツリーもバイナリでソートされる木。
バイナリソートツリーの中位トラバーサルは、キーで順序付けられたシーケンスになる可能性があります。
#include <iostream>
using namespace std;
template<class DataType>
struct BiNode{
DataType data;
BiNode *lchild, *rchild;
};
class BiSortTree {
public:
BiSortTree(int a[ ], int n);
~ BiSortTree( ){Release(root);}
void InOrder( ){InOrder(root);}
BiNode *InsertBST(int x) {return InsertBST(root, x);}
BiNode *SearchBST(int k) {return SearchBST(root, k);}
void DeleteBST(BiNode *p, BiNode *f );
private:
void Release(BiNode *bt);
BiNode *InsertBST(BiNode *bt , int x);
BiNode *SearchBST(BiNode *bt, int k);
void InOrder(BiNode *bt);
BiNode *root;
};
バイナリソートツリーの挿入
void InsertBST(BiNode *&root、BiNode * s);
分析:バイナリソートツリーが空のツリーの場合、新しく挿入されたノードが新しいルートノードで、それ以外の場合、新しく挿入されたノードこれは、挿入位置が検索プロセスによって取得される新しいリーフノードである必要があります。
バイナリソートツリーの挿入アルゴリズム:バイナリソートツリーが空のツリーの場合、新しく挿入されたノードは新しいルートノードです。それ以外の場合、挿入された値がルートノードの値より大きい場合は、右側のサブツリーに挿入します。 ;それ以外の場合は、左側のサブツリーに挿入します。再帰的に。
BiNode *BiSortTree::InsertBST(BiNode *bt, int x)
{
if (bt == NULL){
BiNode *s = new BiNode;
s->data = x;
s->lchild = NULL;
s->rchild = NULL;
bt = s;
return bt;
}
else if (bt->data > x)
bt->lchild = InsertBST(bt->lchild, x);
else
bt->rchild = InsertBST(bt->rchild, x);
}
バイナリソートツリー構造
空のバイナリソートツリーから、順次つのノードずつ挿入し始めます。
BiSortTree::BiSortTree(int a[ ], int n)
{
root = NULL;
for (int i = 0; i < n; i++)
root = InsertBST(root, a[i]);
}
削除バイナリ・ソートツリー
ソートノードを削除、ツリーバイナリ後には、特徴的なバイナリ・ソートツリーのまま。
次の3つの状況で話し合い
ます。1。削除されたノードはリーフです
。2。削除されたノードには左サブツリーまたは右サブツリーのみがあります。3。
削除されたノードには左サブツリーと右サブツリーの両方があります。。
ケース1-削除されたノードがリーフノードである
操作:親ノードの対応するポインターフィールドの値をnullに変更します。
ケース2-削除されたノードには、左のサブツリーまたは右のサブツリーのみがある
操作:親ノードの対応するポインターフィールドの値を、削除されたノードの左のサブツリー(または右のサブツリー)にポイントします。
ケース3-削除されたノードには、左サブツリーと右サブツリーの両方があります。
操作:先行ノード(左サブツリーの最大値)に置き換えてから、先行ノードを削除します。
アクション:後続ノード(右側のサブツリーの最小値)に置き換えてから、前駆ノードを削除してください。
バイナリソートツリーのアルゴリズムの削除-疑似コード
1.ノードpがリーフの場合、ノードpを直接削除します
。2。ノードpに左のサブツリーしかない場合は、pの左のサブツリーのみを再接続する必要があります。ノードpに右のサブツリーしかない場合は、pの右のサブツリーを再接続するだけです
。3。ノードpの左と右のサブツリーが空でない場合、
3.1はノードpの右のサブツリーで左下のノードsを見つけます。そしてs親ノードpar;
3.2ノードsのデータフィールドを削除されたノードpのデータフィールドに置き換えます;
3.3 ノードp の右の子に左のサブツリーがない場合、sの右のサブツリーをパーの右に接続しますサブツリー上;それ以外の場合は、sの右側のサブツリーをノードparの左側のサブツリーに接続します;
3.4ノードsを削除します。
void BiSortTree::DeleteBST(BiNode<int> *p, BiNode<int> *f )
{
if (!p->lchild && !p->rchild)
{
if(f->child==p)
f->lchild= NULL;
else
f->lchild= NULL;
delete p;
}
else if (!p->rchild)
{
if(f->child==p)
f->lchild=p->lchild;
else
f->rchild=p->lchild;
delete p;
}
else if (!p->lchild)
{
if(f->child==p)
f->lchild=p->rchild;
else
f->rchild=p->rchild;
delete p;
}
else
{
par=p;
s=p->rchild;
while (s->lchild!=NULL)
{
par=s;
s=s->lchild;
}
p->data=s->data;
if (par==p)
p->rchild=s->rchild;
else
par->lchild=s->rchild;
delete s;
}
}
バイナリ・ソートツリーを探す
バイナリ・ソートツリープロセスにおけるkの与えられた値を見つけるために:
⑴ルートツリー場合は空で、検索に失敗した。
⑵K = root->データならば、検索が成功し、そうでない場合
⑶kの場合< root->データ、ルートの左側のサブツリーで検索、それ以外の場合は、ルート
の右側のサブツリーで検索します。
上記のプロセスは、kが見つかるか、検索するサブツリーが空になるまで続きますが、検索するサブツリーが空の場合、検索は失敗します。
バイナリソートツリーの検索効率は、2つのサブツリーのうち1つだけを検索する必要があることです。
BiNode *BiSortTree::SearchBST(BiNode<int> *root, int k)
{
if (root==NULL)
return NULL;
else if (root->data==k)
return root;
else if (k<root->data)
return SearchBST(root->lchild, k);
else
return SearchBST(root->rchild, k);
}
バイナリソートツリーの検索パフォーマンス分析バイナリソートツリーの検索パフォーマンスは、バイナリソートツリーの形状(O(log2n)とO(n)の間)に依存します。