二叉查找树实际是一颗数据域有序的二叉树,即对树上的每个结点,都满足其左子树上所有结点的数据域均小于或等于根结点的数据域,右子树上所有结点的数据域均大于根结点的数据域。
定义结构体:
struct node{
int data; //数据域
node *lchild,*rchild; //指针域
}Node;
查找操作:
void search(node* root,int x){
if(root==NULL){ //空树,查找失败
printf("search failed\n");
return ;
}
if(x==root->data){ //查找成功,访问之
printf("%d\n",root->data);
}
else if(x<root->data){ //如果x比根结点的数据域小,说明x在左子树
search(root->lchild,x); //往左子树搜索x
}
else{ //如果x比根结点的数据域大,说明x在右子树
search(root->rchild,x); //往右子树搜索x
}
}
插入操作:
//生成一个新的结点
node* newNode(int v){
node* Node=new node; //申请一个node型变量的地址空间
Node->data=v; //结点权值为v
Node->lchild=Node->rchild=NULL; //初始状态下没有左右孩子
return Node; //返回新建结点的地址
}
//insert函数将在二叉树中插入一个数据域为x的新结点(注意参数root要加引用&)
void insert(node* &root,int x){
if(root==NULL){ //空树,说明查找失败,也即插入位置
root=newNode(x); //新建结点,权值为x
return ;
}
if(x==root->data){ //查找成功,说明结点已纯在,直接返回
return ;
}
else if(x<root->data){ //如果x比根节点的数据域小,说明x需要插在左子树
insert(root->lchild,x); //往左子树搜索x
}
else{ //如果x比根结点的数据域大,说明x需要插在右子树
insert(root->rchild,x); //往右子树搜索x
}
}
创建二叉树操作:
//创建一颗二叉树
node* Create(int data[],int n){
node* root=NULL; //新建根结点root
for(int i=0;i<n;i++)
insert(root,data[i]); //将data[0]-data[n-1]插入二叉查找树中
return root; //返回根结点
}
删除操作:
利用结点左子树中的最右结点或结点右子树中的最左结点代替被删除的结点,实现删除操作
//寻找以root为根结点的树中的最大权值结点
node* findMax(node* root){
while(root->rchild!=NULL){
root=root->rchild; //不断往右,直到没有右孩子
}
return root;
}
//寻找以root为根结点的树中的最小权值结点
node* findMin(node* root){
while(root->lchild!=NULL){
root=root->lchild; //不断往左,直到没有左孩子
}
return root;
}
//删除以root为根结点的树中权值为x的结点
void deleteNode(node* &root,int x){
if(root==NULL) //不存在权值为x的结点
return ;
if(root->data==x){ //找到欲删除的结点
if(root->lchild==NULL&&root->rchild==NULL){ //叶子结点直接删除
root=NULL;
}
else if(root->lchild!=NULL){ //左子树不为空
node* pre=findMax(root->lchild); //找root前驱
root->data=pre->data; //用前驱覆盖root
deleteNode(root->lchild,pre->data); //往左子树中删除结点pre
}
else{ //右子树不为空
node* next=findMin(root->rchild); //找root后继
root->data=next->data; //用后继覆盖root
deleteNode(root->rchild,next->data); //往右子树中删除结点next
}
}
else if(root->data>x){
deleteNode(root->lchild,x); //往左子树中删除
}
else{
deleteNode(root->rchild,x); //往右子树中删除
}
}