二叉查找树
1.插入一个数值
2.查询是否包含某个数值
3.删除某个节点
如果左孩子存在分为两种情况,一个是左孩子没有右孩子,直接把data值替换,free掉下面的节点就行;如果有右孩子,就找到右孩子,并且记录一下最大的右孩子的父节点,然后把data替换一下,删掉节点,但是最大的这个节点可能会有左孩子,还要将左孩子连在父节点的右孩子上面;
如果左孩子不存在,要将右孩子提到上面,注意这个时候是直接进行的,并不是data值替换,所以会用到删除节点的父节点,判断一下删除节点是父节点的左还是右孩子,然后将右孩子直接连到父节点上面,Free掉删除节点
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <ctype.h>
#define maxn 100010
//二叉查找
typedef struct LNode{
int data;
struct LNode *lchild,*rchild;
}LNode;
void *Insert(LNode * &T,int x){
if(!T){
T=(LNode*)malloc(sizeof(LNode));
T->data=x;
T->lchild=NULL;
T->rchild=NULL;
}
else{
if(x<T->data) Insert(T->lchild,x);
else if(x>T->data) Insert(T->rchild,x);
}
}
bool Find(LNode *p,int x){
if(!p) return false;
if(p->data==x) return true;
if(x<p->data) Find(p->lchild,x);
else if(x>p->data) Find(p->rchild,x);
}
bool Delete(LNode * &T,int x){//p还是代表的是根节点,但是有一个查找,所以最后的进行操作的是要删除的节点
LNode *p=T;LNode *s,*f;
if(!T) return false;
else{
while(p){
if(p->data==x) break;
else {
s=p;
if(x<p->data) p=p->lchild;
else p=p->rchild;
}
}
//找到
if(p){
if(p->lchild){
//删除节点的左孩子没有右孩子,直接把左孩子提上去
if(!p->lchild->rchild){
p->data=p->lchild->data;
free(p->lchild);
p->lchild=NULL;
}
else{//找到最大的
LNode *f,*q=p->lchild;
while(q->rchild){f=q;q=q->rchild;}
p->data=q->data;
f->rchild=q->lchild;
free(q);
}
}
else if(!p->lchild){
if(!s){
T=p->rchild;
}
else{
if(s->lchild==p){
s->lchild=p->rchild;
}
else s->rchild=p->rchild;
free(p);
}
}
return true;
}
else return false;
}
}
void Print(LNode *T){
if(!T) return;
else{
Print(T->lchild);
printf("%d ",T->data);
Print(T->rchild);
}
}
int main(){
LNode *T=NULL;
int n;
scanf("%d",&n);
while(n--){
int value;
scanf("%d",&value);
Insert(T,value);
}
Print(T);printf("\n");
int m;
while(scanf("%d",&m)!=EOF){
Delete(T,m);
Print(T);printf("\n");
}
}
//12
//7
//2 15
//1 5 10 17
//4 8 11 16 19
//4
//7
//2 15
//5