二叉排序查找树

来源:互联网 发布:cctv视频下载软件 编辑:程序博客网 时间:2024/04/30 10:29
#include<stdio.h>#include<stdlib.h>typedef int datatype;typedef struct bi_search_tree{    datatype key;    struct bi_search_tree  *left, *right;}* bst_tree;bst_tree BiTreeSearch(bst_tree T,bst_tree PT,int v){if(T==NULL){return PT;}if(T->key==v)return NULL;else{if(T->key>v){BiTreeSearch(T->left,T,v);}else{BiTreeSearch(T->right,T,v);}}}int BiTreeInsert(bst_tree T,int v){bst_tree tmp=NULL;tmp=BiTreeSearch(T,T,v);if(tmp==T&&T->key==0)//初始化判断条件 {T->key=v;return 1;}if(tmp==NULL)//tmp==NULL表示二叉排序树里存在该元素 return 0;//表示插入失败 else{//(*tmp)=(bst_tree)malloc(sizeof(bst_tree));if(tmp->key>v){tmp->left=(bst_tree)malloc(sizeof(bst_tree));tmp->left->key=v;tmp->left->left=NULL;tmp->left->right=NULL;}else{tmp->right=(bst_tree)malloc(sizeof(bst_tree));tmp->right->key=v;tmp->right->left=NULL;tmp->right->right=NULL;}return 1;//1表示插入成功 }} void print(bst_tree T){if(T->left!=NULL)print(T->left);if(T!=NULL) printf("%d\n",T->key);if(T->right!=NULL)print(T->right);} int main(){int arr[]={0,37,0,56,05,13,19,21,64,88,75,80,92};int i,len=sizeof(arr)/sizeof(int);int n;int v; bst_tree T=(bst_tree)malloc(sizeof(bst_tree));T->key=0;T->left=T->right=NULL;for(i=0;i<len;i++){BiTreeInsert(T,arr[i]);}print(T);printf("请输入查询次数:\n");scanf("%d",&n);while(n--){printf("请输入查询值:");scanf("%d",&v); if(BiTreeSearch(T,T,v)==NULL)printf("k=%d 查询成功\n",v);elseprintf("k=%d 查询失败\n",v); }}
总结:由于没用用到C++,所以无法用到引用运算符“&”,这使本程序的构建复杂了些许。
本人程序设计的关键问题在于查找二叉树的初始化问题以及传指针到函数的问题。

问题1:由于初始化时二叉树是棵空树,初始化阶段的设计逻辑属于二叉树查找与插入的边界问题(边界问题常常需要单独考虑),所以冥思苦想设计了这么几行代码:

if(tmp==T&&T->key==0)//初始化判断条件 {T->key=v;return 1;}
这里在主函数里设置了这样的初始状态:

T->key=0;T->left=T->right=NULL;
虽然设置初始值为0,但并不影响后面插入0元素,因为如果有0元素插入,则查找函数会返回NULL,此时就默认了0在该树了。然后如果是空树的话,首个元素的插入必然返回的是根节点的指针,这样就可以通过以上判断条件解决初始化问题。

问题2

由于构建二叉树是在函数中进行的,所以传的参数都会被复制成为副本(这意味着不会直接对实参进行修改),所以常规的做法是传指针进行操作,但如果是这样的思路的话,问题又来了,怎么传指针,是直接传指针进去还是想别的办法,如果直接传指针的话,由于指针传进去是其存贮的值是NULL,所以副本也会为NULL,这就整个过程将对指向NULL的指针进行操作,结果可想而知。一种解决办法是传二级指针像**p这样的,这样先对传进去的指针先取址,再引用就会对直接对指针变量本身进行操作,但这样会使函数显得有些麻烦。于是本人又冥思苦想想到了第二种方案,那就是先在主函数中分配一个地址给指针变量,在将指针传入函数。我们可以分析一下函数参数的处理过程,首先实参传入函数,由于参数类型是指针,所以副本将会被复制一份地址,这里将会把实参所存储的值赋给副本,不难发现,这里复制的值正式实参所存储的地址,所以后续整个过程实际上也是对地址进行操作,这个操作的对象就是主方法里的malloc返回的值,而本人在主方法里用T存储了这个地址,所以操作完之后,直接用T就可以对整棵树进行操作。

bst_tree T=(bst_tree)malloc(sizeof(bst_tree))

2 0
原创粉丝点击