一棵二叉搜索樹由一棵二叉樹來組織,可以用鏈表數據結構來表示,每個結點除了Key和衛星數據,還包含指針left,right,p,分別指向左子樹,右子樹和雙親。
二叉樹中的key總是滿足二叉搜索樹性質:
設x是二叉搜索樹的一個結點,若y是x左子樹中的一個結點,則y.key< x.key;若y是x右子樹中的一個結點,則y.key>=x.key。(相等時,放在左子樹還是右子樹看個人習慣,此文是放在右子樹中)
#include<iostream>
using namespace std;
//template<class A>
struct BSTNode{
//A value;//衛星數據
int key;//排序關鍵字
BSTNode *lchild = nullptr;//指向左孩子
BSTNode *rchild = nullptr;//指向右孩子
BSTNode *p = nullptr;//指向雙親
};
struct Tree{
BSTNode *root = nullptr;
};
//中序遍歷,先序遍歷,後序遍歷,O(n)
void inorder_tree_walk(BSTNode *x){
if(x != nullptr){
inorder_tree_walk(x->lchild);
cout << x->key<<" ";
inorder_tree_walk(x->rchild);
}
}
void preorder_tree_walk(BSTNode *x){
if(x != nullptr){
cout << x->key <<" ";
preorder_tree_walk(x->lchild);
preorder_tree_walk(x->rchild);
}
}
void postorder_tree_walk(const BSTNode *x){
if(x != nullptr){
postorder_tree_walk(x->lchild);
postorder_tree_walk(x->rchild);
cout << x->key <<" ";
}
}
//迭代查找
BSTNode* iterative_tree_search(BSTNode *x,int v){
while(x !=nullptr && x->key != v){
if(v < x->key)
x = x->lchild;
else
x = x->rchild;
}
return x;
}
//遞歸查找
BSTNode* tree_search(BSTNode *x,int v){
if(x == nullptr || x->key == v)
return x;
if(v < x->key)
return tree_search(x->lchild,v);
else
return tree_search(x->rchild,v);
}
//最小關鍵字元素
BSTNode* tree_minimum(BSTNode *x){
while(x->lchild != nullptr)
x = x->lchild;
return x;
}
//最大關鍵字元素
BSTNode* tree_maximum(BSTNode *x){
while(x->rchild != nullptr)
x = x->rchild;
return x;
}
//後繼,前驅,O(h)
BSTNode* tree_successor(BSTNode *x){
if(x->rchild != nullptr)
return tree_minimum(x->rchild);
BSTNode *y = x->p;
while(y != nullptr && x == y->rchild){
x = y;
y = y->p;
}
return y;
}
BSTNode* tree_predecessor(BSTNode *x){
if(x->lchild != nullptr)
return tree_minimum(x->rchild);
BSTNode *y = x->p;
while(y != nullptr && x == y->lchild){
x = y;
y = y->p;
}
return y;
}
//插入
void tree_insert(Tree &T,BSTNode *z){
BSTNode *y = nullptr;
BSTNode *x = T.root;
while(x != nullptr){
y = x;
if(z->key < x->key)
x = x->lchild;
else
x = x->rchild;
}
z->p = y;
if(y == nullptr)
T.root = z;
else if(z->key < y->key)
y->lchild = z;
else
y->rchild = z;
}
/*刪除*/
//將v的雙親換成u的雙親
void transplant(Tree &T,BSTNode *u,BSTNode *v){
if(u->p == nullptr)
T.root = v;
else if(u == u->p->lchild)
u->p->lchild = v;
else
u->p->rchild = v;
if(v != nullptr)
v->p = u->p;
}
void tree_delete(Tree &T,BSTNode *z){
if(z->lchild == nullptr)
transplant(T,z,z->rchild);
else if(z->rchild == nullptr)
transplant(T,z,z->lchild);
else{
BSTNode *y = tree_minimum(z->rchild);
if(y->p != z){
transplant(T,y,y->rchild);
y->rchild = z->rchild;
y->rchild->p = y;
}
transplant(T,z,y);
y->lchild = z->lchild;
y->lchild->p = y;
}
}
//測試代碼
int main(){
Tree T;
int k,n;
cout<<"個數:";
cin>>n;
while(n--){//輸入#結束
cin>>k;
BSTNode *a = new BSTNode();
a->key = k;
tree_insert(T,a);
}
cout<<"中序輸出:";
inorder_tree_walk(T.root);//輸出
BSTNode *median;
cout<<"\n輸入要刪除的節點:";
int v;
cin>>v;
median = iterative_tree_search(T.root,v);//查找key==8的節點
cout<<v<<"的後繼"<<tree_successor(median)->key<<endl;
cout<<v<<"的前驅"<<tree_predecessor(median)->key<<endl;
cout<<"刪除"<<v<<"得到:";
tree_delete(T,median);//,然後刪除該節點
inorder_tree_walk(T.root);//輸出
median = tree_minimum(T.root);
cout<<"\nmininum:"<<median->key<<endl;
cout<<"刪除最小值得到:";
tree_delete(T,median);
inorder_tree_walk(T.root);//輸出
median = tree_maximum(T.root);
cout<<"\nmaxinum:"<<median->key<<endl;
cout<<"刪除最大值得到:";
tree_delete(T,median);
inorder_tree_walk(T.root);//輸出
cout<<endl;
}