由于输入的数据顺序不同,建立的bst会不一样。最坏的情况就是一个链,所以我们引入了平衡二叉树的概念。这里我们先来看binary search tree。(我随笔里面有一些相关知识)
建立(也就是插入)
bstree insert(bstree t,element num){
//空树
if(!t){
t=(bstree)malloc(sizeof(binode));
t->data=num;
t->l=t->r=NULL;
}
else{
if(num<t->data) t->l=insert(t->l,num);
else if(num>t->data) t->r=insert(t->r,num);
}
return t;
}
---------------------------------
建立(非递归版)
bstree insert(bstree t,element num){
bstree x=t;
bstree y=NULL;//作为num正确位置的父节点
while(x){
y=x;
if(num<x->data) x=x->l;
else if(num>x->data) x=x->r;
}
//新树
if(!y){
t=(bstree)malloc(sizeof(binode));
t->l=t->r=NULL;
t->data=num;
}
else if(num<y->data){
bstree tep=(bstree)malloc(sizeof(binode));
tep->data=num;
tep->l=tep->r=NULL;
y->l=tep;
}
else if(num>y->data){
bstree tep=(bstree)malloc(sizeof(binode));
tep->data=num;
tep->l=tep->r=NULL;
y->r=tep;
}
return t;
}
----------------------------------------
删除
bstree deletbstree(bstree t,element x){
ptr tep;
if(!t){
printf("未找到该元素\n");
return NULL;
}
else//首先要找到该元素所在的位置,然后看他有无子树。
{
if(x<t->data) t->l=deletbstree(t->l,x);
else if(x>t->data) t->r=deletbstree(t->r,x);
else//find it's position
{
if(t->l&&t->r)//左右子树全有。
{
tep=findmin(t->r);//这里我们把右子树中最小的元素作为删除节点的代替。
t->data=tep->data;
t->r=deletbstree(t->r,t->data);//删除最小的元素节点
}
else
{
tep=t;
//只有右子树,或者没有子树
if(!t->l) t=t->r;
else t=t->l; //只有左子树。
free(tep);
}
}
}
return t;
}
----------------------------------------------
查找
bstree bstreesearch(bstree t,element x)
{
while(t&&t->data!=x)
{
if(x<t->data) t=t->l;
else t=t->r;
}
if(!t){//上面while的判断必须t在前面,这一步才有效。
//因为当找不到元素时,t=null,while第一个判断是t->data,程序错误终止
//当第一个判断是t的时候,t=null,自然正常结束程序
printf("没有找到");
return NULL;
}
return t;
}
------------------------------------
全部代码
#include<stdio.h>
#include<stdlib.h>
typedef struct Node* ptr;
typedef int element;
typedef struct Node{
ptr l,r;
element data;
}binode,*bstree;
//上面定义的是树,下面是队列
typedef struct node* position;
struct node{
position next;
bstree data;
};
typedef struct Qnode* queue;
struct Qnode{
position front,rear;
};
bool isempty(queue q){
return (q->front==NULL);
}
queue creatqueue()
{
queue q=(queue)malloc(sizeof(struct Qnode));
q->front=q->rear=NULL;
return q;
}
bool addq(queue q,bstree t)
{
position tep=(position)malloc(sizeof(struct node));
tep->data=t;
tep->next=NULL;
if(q->front==NULL){
q->front=q->rear=tep;
}
else{
q->rear->next=tep;
q->rear=tep;
}
return true;
}
bstree deletq(queue q){
if(isempty(q)) return NULL;
bstree tep=q->front->data;
position te=q->front;
if(q->front==q->rear){
q->front=q->rear=NULL;
}
else
{
q->front=q->front->next;
}
free(te);
return tep;
}
void disbstree(bstree bt){
bstree t;
queue q=creatqueue();
addq(q,bt);
while(!isempty(q)){
t=deletq(q);
printf("%d ",t->data);
if(t->l) addq(q,t->l);
// else printf("#");
if(t->r) addq(q,t->r);
// else printf("#");
}
}
bstree insert(bstree t,element num){
bstree x=t;
bstree y=NULL;//作为num的正确位置
while(x){
y=x;
if(num<x->data) x=x->l;
else if(num>x->data) x=x->r;
}
//新树
if(!y){
t=(bstree)malloc(sizeof(binode));
t->l=t->r=NULL;
t->data=num;
}
else if(num<y->data){
bstree tep=(bstree)malloc(sizeof(binode));
tep->data=num;
tep->l=tep->r=NULL;
y->l=tep;
}
else if(num>y->data){
bstree tep=(bstree)malloc(sizeof(binode));
tep->data=num;
tep->l=tep->r=NULL;
y->r=tep;
}
return t;
}
void freebstree(bstree t){
if(t){
if(t->l) freebstree(t->l);
if(t->r) freebstree(t->r);
free(t);
}
}
ptr findmax(bstree t){
while(t->r){
t=t->r;
}
return t;
}
ptr findmin(bstree t){
while(t->l){
t=t->l;
}
return t;
}
bstree deletbstree(bstree t,element x){
ptr tep;
if(!t){
printf("未找到该元素\n");
return NULL;
}
else//首先要找到该元素所在的位置,然后看他有无子树。
{
if(x<t->data) t->l=deletbstree(t->l,x);
else if(x>t->data) t->r=deletbstree(t->r,x);
else//find it's position
{
if(t->l&&t->r)//左右子树全有。
{
tep=findmin(t->r);//这里我们把右子树中最小的元素作为删除节点的代替。
t->data=tep->data;
t->r=deletbstree(t->r,t->data);//删除最小的元素节点
}
else
{
tep=t;
//只有右子树,或者没有子树
if(!t->l) t=t->r;
else t=t->l;
free(tep);
}
}
}
return t;
}
bstree bstreesearch(bstree t,element x)
{
while(t&&t->data!=x)
{
if(x<t->data) t=t->l;
else t=t->r;
}
if(!t){
printf("没有找到");
return NULL;
}
return t;
}
int main(void){
int n;
bstree bt=NULL;
while(scanf("%d",&n),n!=-1)//数据输入结束标志,-1
{
bt=insert(bt,n);
printf("插入successfully\n");
}
disbstree(bt);
ptr max=findmax(bt);
ptr min=findmin(bt);
printf("最大的 %d\n",max->data);
printf("最小的 %d\n",min->data);
printf("请输入要删除节点元素的值\n");
element data;
scanf("%d",&data);
bt=deletbstree(bt,data);
printf("删除之后的binary search tree 为\n");
disbstree(bt);
printf("请输入要查找的元素\n");
scanf("%d",&data);
ptr tt=bstreesearch(bt,data);
if(tt) printf("找到他的位置并打印他的值 %d\n",tt->data);
freebstree(bt);
}