首先,给出二叉排序树的定义:
二叉排序树是一棵二叉树,它或者为空,或者满足以下条件:
1.若左子树不空,则左子树上所有结点的值均小于根的值
2.若右子树不空,则右子树上所有结点的值均大于根的值
3.其左右子树均为二叉排序树
我们根据定义可以知道,二叉排序树的中序序列是非降序序列
在本文中,主要涉及二叉排序树的三大操作,构造,插入,删除节点
1.构造二叉排序树
用户输入节点的值,判断是否为结束符,若不是,则继续插入节点到树中
2.插入操作
如果是空树,则插入节点成为根节点。若该节点的值小于根节点的值,插入到左子树中,否则插入到右子树中
3.删除节点
笼统地说,就是找到要删除节点,然后将它左子树的最右边的节点找出来,顶替要删除的节点。
#include <iostream>
using namespace std;
const int End_Of_Num = -1; //表示结束符号
typedef struct Bnode{
int key;
struct Bnode *lchild;
struct Bnode *rchild;
}Bnode,*Tree;
void insert(Bnode *&T,Bnode *S){ //将指针S所指节点插入到二叉排序树T中
if(T == NULL) //若插入到空树中,插入节点成为根节点
T = S;
else if(S->key < T->key)
insert(T->lchild,S);
else
insert(T->rchild,S);
}
void create_bst(Bnode *&T){ //建立二叉排序树
Bnode *u;
T = NULL;
int x;
cin>>x;
while(x!=End_Of_Num){
u = new Bnode;
u->key = x;
u->lchild = NULL;
u->rchild = NULL;
insert(T,u);
cin>>x;
}
}
void inorderVisit(Tree T){ //中序遍历
if(T != NULL){
inorderVisit(T->lchild);
cout<<T->key<<" ";
inorderVisit(T->rchild);
}
}
void Delete(Tree T,int x){ //删除节点
Tree f,p = T;
while(p && p->key !=x){
if(p->key > x){
f = p;
p = p->lchild;
}
else{
f = p;
p = p->rchild;
}
}
if(p == NULL) return; //表示没找到
if(p->lchild == NULL){
if(f->lchild == p)
f->lchild = p->rchild;
else
f->rchild = p->rchild;
}
else{ //被删结点有左子树
Tree q = p->lchild;
Tree s = q;
while(q->rchild != NULL){
s = q;
q = q->rchild;
}
if(s == p->lchild){ //p的左子树的根节点无左右孩子
p->lchild = s->lchild;
p->key = s -> key;
free(s);
}
else{
p->key = q->key;
s->rchild = q->lchild;
free(q);
}
}
}
int main(){
Bnode *T;
create_bst(T); //建立二叉排序树
inorderVisit(T); //中序遍历二叉排序树,从小到大输出
Delete(T,100);
cout<<endl;
inorderVisit(T);
return 0;
}