12 二叉树-链式存储-二叉排序树(BST)

呜呜 写这个东西花了我2天 居然花了两天!!我还要写AVL呢啊啊啊啊啊啊啊!!!!!!

等下还要跑去上自习 大早上起来脸都没洗现在先赶紧发博客 昨晚写出来了独自在其他人都睡着了的宿舍狂喜乱舞。。

迷之想哭 不知道能不能考上。。。。。。

不管能不能考上 活在当下就对了 走好每一步踏踏实实吧!!

删除操作的代码考虑了很多东西,自己写的时候一开始觉得有点抽象,特别是左右孩子链接的处理,还有是否是根结点的判别……

其实也不知道我这个写法对不对,看了一些网上的代码,别人的都写得好简单啊!

先这么写着吧,回头有空了我再思考下有没有更简单的实现方法!如果有网友有好建议也欢迎留言!


1、二叉排序树的定义:

 或者是一棵空树,或者是一颗具有以下特性的非空二叉树:

(1)若左(右)子树非空,则右(左)子树上的关键字值均小(大)于根结点的关键字值。

(2)左、右子树本身也分别是一颗二叉树。

2、二叉排序树的特点:

(1)对二叉排序树进行中序遍历可以得到一个递增的有序序列。

(2)维护的时候只需修改指针就可以完成插入和删除操作,平均执行时间为O(log2n)。

(3)平均查找性能取决于树的高度,最糟糕的情况下:由于输入的序列是有序的,形成了倾斜单支二叉树(可以理解为变成一个单链表),查找效率降成O(n)(平均查找长度与单链表相同)。

(4)查找判定树不唯一。

3、二叉排序树的适用场合:

有序表是动态查找表的时候应选择二叉排序树作为其逻辑结构。(静态查找表则合适用顺序表)


4、代码实现

注释详见代码!这里不赘述了!如果有不明白或者有错的地方欢迎留言和指正!

包括:

①二叉排序树的建立(包含插入操作)

②二叉排序树的查找

③二叉排序树的删除

④为了写删除操作还增加了一个判别孩子结点是双亲结点的左孩子or右孩子的小函数……

【注】因为此代码算法是自己思考设计的,自己比较笨拙,可能会有实现很冗余的地方,如果要使用建议参考其他人的版本。。可能只合适做数据结构的学习理解用orz

  1 #include<iostream>
  2 #include<stdlib.h>
  3 #include<cstdio>
  4 #include<stack>
  5 #include<queue>
  6 using namespace std;
  7 #define TRUE 1
  8 #define FALSE 0
  9 #define OK 1
 10 #define ERROR 0
 11 #define OVERFLOW -2
 12 typedef int Status;
 13 typedef int ElemType;
 14 /*存储结构描述*/
 15 typedef struct BitNode
 16 {
 17     int data;
 18     struct BitNode *lchild,*rchild;
 19 } BitNode,*BiTree;
 20 /*建立一个二叉排序树*/
 21 /*其实是二叉排序树的插入算法*/
 22 void initTree(BiTree &T,int x)
 23 {
 24     if(T==NULL)
 25     {
 26         T=(BitNode*)malloc(sizeof(BitNode));
 27         T->data=x;
 28         T->lchild=NULL;
 29         T->rchild=NULL;
 30     }
 31     else
 32     {
 33         if(x>T->data)
 34             initTree(T->rchild,x);
 35         else initTree(T->lchild,x);
 36     }
 37 }
 38 /*二叉排序树的结点查找*/
 39 /*
 40 1、如果查找成功,返回查找的结点
 41 2、如果查找失败 返回NULL(走到了叶子结点的下一层→【NULL】)
 42 3、指针p指向结点的双亲结点
 43 */
 44 BitNode *BST_Search(BiTree T,int x,BitNode *&p)
 45 {
 46 
 47     p=NULL;
 48     while(T!=NULL&&x!=T->data)
 49     {
 50         p=T;
 51         if(x<T->data)
 52             T=T->lchild;
 53         else T=T->rchild;
 54     }
 55     return T;
 56 }
 57 /*结点的删除*/
 58 /*
 59 1、如果是叶结点,直接删除即可
 60 2、如果删除的结点只有单枝左子树或者右子树→让子树成为父结点的子树,直接替代被删结点的位置
 61 3、如果删除的结点有左右两棵子树,这里可以采用p的(x序遍历)直接后继或者直接前驱进行替代。
 62    这里选为中序遍历的直接后继作为替代结点,其中序遍历下的直接后继为被删除结点右子树最左结点。
 63 4、在最后链接被删结点双亲和被删结点孩子的这一步中,如果被删结点为根结点,则不需修改它双亲结点(本来就没双亲),但是要修改指向树的指针T!!不然它会指向空域。
 64 */
 65 int relationship(BitNode *a,BitNode *b)
 66 {
 67     if(a->lchild==b) return 1;//b是a的左孩子
 68     else if(a->rchild==b) return 2;//b是a的右孩子
 69     else return 3;//没关系
 70 }
 71 
 72 int Delete(BiTree &T,int x)
 73 {
 74     BitNode *p=NULL,*psdad=NULL;
 75     BitNode *tool=NULL,*tooldad=NULL;
 76     p=BST_Search(T,x,psdad);
 77     //如果删除的结点是叶结点
 78     if(p->lchild==NULL&&p->rchild==NULL)
 79     {
 80         if(relationship(psdad,p)==1)
 81         {
 82             psdad->lchild=NULL;
 83         }
 84         else
 85         {
 86             psdad->rchild=NULL;
 87         }
 88         free(p);
 89     }
 90     else if(p->lchild==NULL)
 91     {
 92         if(relationship(psdad,p)==1)
 93         {
 94             psdad->lchild=p->rchild;
 95             free(p);
 96         }
 97         else
 98         {
 99             psdad->rchild=p->rchild;
100             free(p);
101         }
102     }
103     else if(p->rchild==NULL)
104     {
105         if(relationship(psdad,p)==1)
106         {
107             psdad->lchild=p->lchild;
108             free(p);
109         }
110         else
111         {
112             psdad->rchild=p->lchild;
113             free(p);
114         }
115     }
116     else//p有左右两棵子树//有错,明天思考
117     {
118         tooldad=p;
119         tool=p->rchild;
120         /*转向右子树,向左走到尽头*/
121         //cout<<"tool1:"<<tool->data<<endl;
122         //if(tooldad!=NULL)
123         //    cout<<"tooldad:"<<tooldad->data<<endl;
124         //else cout<<"tooldad:null"<<endl;
125 
126         while(tool->lchild)
127         {
128             tooldad=tool;
129             tool=tool->lchild;
130         }
131 
132         //cout<<"tool2:"<<tool->data<<endl;
133         //if(tooldad!=NULL)
134           //  cout<<"tooldad:"<<tooldad->data<<endl;
135         //else cout<<"tooldad:null"<<endl;
136         if(tool==p->rchild)//即:被删除结点右子树的中序遍历第一个结点就是右孩子,这时直接把右孩子挪上去代替被删结点
137         {
138             //cout<<"ct1"<<endl;
139             tool->lchild=p->lchild;
140             if(psdad)//如果被删除的不是根结点 则需要把代替原位置的结点和被删结点的双亲接连上去
141             {
142                 if(relationship(psdad,p)==1)
143                 {
144                     psdad->lchild=tool;
145                     free(p);
146                 }
147                 else
148                 {
149                     psdad->rchild=tool;
150                     free(p);
151                 }
152             }
153             else//被删除的是根结点 要把指向根结点的指针一并修改 不然树头会指向空域
154             {T=tool;free(p);}
155         }
156         else
157         {
158             //cout<<"ct2"<<endl;
159             tooldad->lchild=tool->rchild;//当前结点为最左结点,它一定没有左孩子,可能有右孩子。
160             tool->lchild=p->lchild;
161             tool->rchild=p->rchild;
162             tool->lchild=p->lchild;
163             if(psdad)
164             {
165                 if(relationship(psdad,p)==1)
166                 {
167                     psdad->lchild=tool;
168                     free(p);
169                 }
170                 else
171                 {
172                     psdad->rchild=tool;
173                     free(p);
174                 }
175             }
176             else {T=tool;free(p);}
177         }
178     }
179     return OK;
180 
181 }
182 
183 void visit(BiTree T)
184 {
185     cout<<T->data<<' ';
186 }
187 /*中序遍历测试用*/
188 void inOrder(BiTree T)
189 {
190     if(T!=NULL)
191     {
192         inOrder(T->lchild);
193         visit(T);
194         inOrder(T->rchild);
195     }
196 }
197 int main()
198 {
199     BiTree tree=NULL;
200     BitNode *ans=NULL,*ansdad=NULL;
201     int x;
202     cin>>x;
203     while(x!=0)
204     {
205         initTree(tree,x);
206         cin>>x;
207     }
208     cout<<"--- show the bst tree ---"<<endl;
209     inOrder(tree);
210     cout<<endl;
211     cout<<"Test Search function:"<<endl;
212     cin>>x;
213     ans=BST_Search(tree,x,ansdad);
214     if(ans==NULL)
215         cout<<"NULL."<<endl;
216     else
217     {
218         cout<<"successful found."<<ans->data<<endl;
219         if(ansdad!=NULL)
220             cout<<"His father's data is:"<<ansdad->data<<endl;
221         else cout<<"He is the Root of BST tree."<<endl;
222     }
223     int w;
224 
225     cin>>w;
226     while(w!=0)
227     {
228         Delete(tree,w);
229         cout<<"--- show the bst tree ---"<<endl;
230         inOrder(tree);
231         cout<<endl;
232         cin>>w;
233     }
234     return 0;
235 }

5、代码实现截图

原文地址:https://www.cnblogs.com/AKsnoopy/p/7513126.html