すべてのデータ構造、アルゴリズムやアプリケーションカリキュラムのテンプレートをクリックしてください:https://blog.csdn.net/weixin_44077863/article/details/101691360
バイナリ検索ツリー(バイナリ・ソート木)(二分探索木)(BST)
単純な二分探索木、キーのすべてのノードが残っているサブツリーのルートは、以下のすべてのノードのキー値よりは根の右部分木よりも大きいです
これは、到達挿入と検索ログレベルを可能にします
非常に単純な
それについて少し話を削除します。
2つのカテゴリに分かれ削除:削除マージ、削除、コピー
1は、削除合併:現在のノードを削除するには、左の部分木の右部分木はので、2つのドッキングのアイデアがあり、一緒にドッキング
①左サブツリーが削除されたノード、最大の左サブツリーの右側に右サブツリー(右端)ノード(一般的に使用されるコード材料)に移動させます
②右サブツリーに移動すると、接合部で削除最小サブツリーの左および右の部分木(左端)ノード残されます
2、コピーを削除します。
ノードの左の部分木の最大値(右端)の値は、ノードを削除するために割り当てられ、最大接合を削除する①、最大接合部は、ノードは必ずしも正しい息子はないので、それは、はるかに便利であろう削除しましたこれだけの息子への書き込み時間は、ケースが正確にノードの親ノードならば、彼は、彼の息子を残した親ノードの最大接合点の権利であることを、細部に注意を払うにすることができ、この接合部で左に移動しますが、注意が左彼の息子が残されているときに彼女の息子を取り、ノードを削除する(教科書コードが一般的に使用されます)
②右の部分木の最小値は、ノードがノードに割り当てられて削除され(大部分は左)、そしてわずかに、細部の模倣では、この点で最も要約を削除
PS:マージまたはコピーのいずれか削除します削除ノードは唯一のサブツリーこと、そして過去のように直接移動し、その後、左と右のサブツリーは、上記の手段を持っています
そして、ゲント文を削除することを忘れないために時間を削除します。
バイナリ検索ツリーのテンプレートを次のように(つまり一般的に使用されるメソッドを削除します)
template <class T>
class Node{
public:
T x;
Node<T> *l,*r;
Node():l(0),r(0){}
Node(const T& x):x(x),l(0),r(0){}
Node(const T& x, Node<T> *l, Node<T> *r):x(x),l(l),r(r){}
};
template <class T>
class BinarySearchTree{
private:
Node<T> *root;
public:
BinarySearchTree():root(0){}
void insert(const T& x){
Node<T> *p=root,*pre=NULL;
while(p){
pre=p;
if(x>p->x) p=p->r;
else p=p->l;
}
if(!root) root=new Node<T>(x);
else if (x>pre->x) pre->r=new Node<T>(x);
else pre->l=new Node<T>(x);
}
Node<T>* search(T x){
Node<T> *cur=root;
while(cur&&cur->x!=x){
if(x>cur->x) cur=cur->r;
else cur=cur->l;
}
return cur;
}
void delete_copy(T x){//复制删除
Node<T> *p=root,*fa,*pre,*tmp;
while(p&&p->x!=x){
if(x>p->x) fa=p,p=p->r;
else fa=p,p=p->l;
}
if(!p) return;
tmp=p;
if(!(p->r)){//无右子树,左子树复制到被删除结点处
if(root==p) root=p->l;
else if(fa->l==p) fa->l=p->l;
else fa->r=p->l;
}
else if(!(p->l)){//无左子树,右子树复制到被删除结点处
if(root==p) root=p->r;
else if(fa->l==p) fa->l=p->r;
else fa->r=p->r;
}
else{
tmp=p->l;
pre=p;
while(tmp->r){//左子树中最大的
pre=tmp;
tmp=tmp->r;
}
p->x=tmp->x;
if(pre==p) p->l=tmp->l;
else pre->r=tmp->l;
}
delete tmp;
}
void delete_merge(T x){//合并删除
Node<T> *p=root,*fa,*tmp;
while(p&&p->x!=x){
if(x>p->x) fa=p,p=p->r;
else fa=p,p=p->l;
}
if(!p) return;
if(!(p->r)){//无右子树,左子树复制到被删除结点处
if(root==p) root=p->l;
else if(fa->l==p) fa->l=p->l;
else fa->r=p->l;
}
else if(!(p->l)){//无左子树,右子树复制到被删除结点处
if(root==p) root=p->r;
else if(fa->l==p) fa->l=p->r;
else fa->r=p->r;
}
else{
tmp=p->l;
while(tmp->r) tmp=tmp->r;//左子树中最右的
tmp->r=p->r;
tmp=p;
if(p==root) root=p->l;
else if(fa->l==p) fa->l=p->l;//左子树的根结点代替被删除结点
else fa->r=p->l;
}
delete tmp;
}
};