二叉树之搜索树

来源:互联网 发布:可可网络验证后台 编辑:程序博客网 时间:2024/05/28 05:15

       昨天加今天,一直写不好关于二叉搜索树的代码,主要思想没有理解透彻,终于,今天晚上把他们做了出来,也多了许多感悟,具体见代码。

     

/*根据升序数组构造平衡二叉搜索树*/#include <stdio.h>#include <stdlib.h>typedef struct tree_node_s {     char data;     struct tree_node_s *lchild;     struct tree_node_s *rchild;  }tree_node_t, *Tree; //无序数组建立有序二叉树Tree OrderTree(int *a,int length){Tree insertTree(Tree &b,int x);Tree t=NULL;t=(Tree)malloc(sizeof(tree_node_t));t->data=*a;t->lchild=NULL;t->rchild=NULL;for(int i=1;i<length;i++){t=insertTree(t,a[i]);}return t;}//升序建立二叉树Tree BinNodeBuildTree(int *a,int start,int end){int mid =(end+start)/2;Tree t=NULL;int b=a[mid];if(start>end)return t;t=(Tree)malloc(sizeof(tree_node_t));t->lchild=NULL;t->rchild=NULL;t->data=b;t->lchild=BinNodeBuildTree(a,start,mid-1);t->rchild=BinNodeBuildTree(a,mid+1,end);return t;}//先序遍历void PreOrder(Tree b){if(b!=NULL){printf("\t%d",b->data);PreOrder(b->lchild);PreOrder(b->rchild);}}//中序遍历void InOrder(Tree b){if(b!=NULL){InOrder(b->lchild);printf("\t%d",b->data);InOrder(b->rchild);}}//查找节点Tree searchTree(Tree &b,int x){bool solve=false;Tree p; p=b;while(p && !solve) //最后,1.p找到,!solve=false,(p && !solve)=0,跳出循环。               //      2.p未找到,p=NULL,!solve=true,(p && !solve)=0,也跳出循环。{if(x==p->data){printf("已找到%d\n",x);solve=true;return p;}else if(x<p->data){p=p->lchild;}else{p=p->rchild;}}if(p==NULL){printf("没有找到\n");}return b;}//插入节点Tree insertTree(Tree &b,int x){Tree p;p=(Tree)malloc(sizeof(tree_node_t));p->data=x;p->lchild=NULL;p->rchild=NULL;if(b==NULL){return p;}if(p->data < b->data){b->lchild=insertTree(b->lchild,x);}else{b->rchild=insertTree(b->rchild,x);}return b;}//非递归方法插入节点void insertTree2(Tree &b,int x){Tree p;p=(Tree)malloc(sizeof(tree_node_t));p->data=x;p->lchild=NULL;p->rchild=NULL;while(b->lchild!=NULL && b->rchild!=NULL){if(p->data<b->data){b=b->lchild;if(b==NULL){b=p;}}else{b=b->rchild;if(b==NULL){b=p;}}}}//删除节点void deleteTree(Tree &b,int x){Tree p,q;//p为所找的节点,q为所找节点的父节点p=b;while(p!=NULL){if(x==p->data){break;}else if(x>p->data){q=p;p=p->rchild;}else{q=p;p=p->lchild;}}if(p==NULL){printf("无此节点:%d",x);}//若p是叶子节点if(p->lchild==NULL&&p->rchild==NULL){if(p==b)//p是根b=NULL;else if(q->lchild==p){q->lchild=NULL;p=NULL;}else{q->rchild=NULL;p=NULL;}free(p);}//若p为单支节点else if(p->rchild==NULL&&p->lchild!=NULL) //p的右子树为空{if(p==b){if(p->lchild==NULL){b=p->rchild;}else{b=p->lchild;}}else if(q->lchild==p){q->lchild=p->lchild;}else{q->rchild=p->lchild;}free(p);}else if(p->rchild!=NULL&&p->lchild==NULL) //p的左子树为空{if(p==b){if(p->lchild==NULL){b=p->rchild;}else{b=p->lchild;}}else if(q->lchild==p){q->lchild=p->rchild;}else{q->rchild=p->rchild;}free(p);}//p的左右子树均不为空//如果一个结点有右孩子,则该结点的后继,至多有一个子女,而且是右孩子。//因为假如该结点的后继有左孩子和右孩子,那么其左孩子的值肯定是介于该结点和其后继之间的,//那么按照二叉查找树的性质,这个左孩子就应该是该结点的后继,所以,这与原先的后继相互矛盾.else //(p->lchild!=NULL&&p->rchild!=NULL){//找到P的后继节点,即p的右子树的最小值,即右子树的左子书的最后一个值Tree n,m;//n 为p的后继,m 为n的父节点n=p->rchild;while(n->lchild){m=n;n=n->lchild;}p->data=n->data;m->lchild=n->rchild;}}int main (){Tree p=NULL;Tree q=NULL;int a[12]={15,5,16,3,12,20,10,13,18,23,6,7};int b[5]={1,2,3,6,5};p=OrderTree(a,12);InOrder(p);printf("\n");deleteTree(p,5);InOrder(p);printf("\n");/*p=BinNodeBuildTree(a,0,4);q=BinNodeBuildTree(a,0,4);PreOrder(p);printf("\n");insertTree(p,4);PreOrder(p);printf("\n");insertTree2(q,4);PreOrder(p);printf("\n");*/return 0;}

另外,还发现了一个问题,废了我很长时间,代码没有错误,但是就是无法执行到底,发现是用了太多的if,不知道用太多的if还会出问题?我把他们改成了else If,就可以好好执行了,

0 0