二叉排序树的实现和操作

来源:互联网 发布:java aop自定义 编辑:程序博客网 时间:2024/06/04 18:30

先提几个问题,如下:

1.还记得二分查找吗?(对分查找)它是适合于操作什么类型的数据?

2.二叉树,二叉完全树,二叉排序树,堆排序,分别是什么?它们是用来干什么?

3.为什么二叉树要用中序遍历,而不是前或者后序遍历?

好了,这里我给出了,二叉排序树的插入,删除,输出,与查找的用例,具体看代码:

#include<iostream>using namespace std;template <class T>struct BSnode{T d;BSnode* lchild;BSnode* rchild;};template <class T>class BS_Tree{private:BSnode<T>*BT;public:BS_Tree(){BT=NULL;return;}void insert_BS_Tree(T);int delete_BS_Tree(T);BSnode<T>* serch_BS_Tree(T);void intrav_BS_Tree();};template <class T>void BS_Tree<T>::intrav_BS_Tree(){BSnode<T>*p;p=BT;intrav(p);return;}template <class T>static intrav(BSnode<T> *p){if(p!=NULL){intrav(p->lchild);cout<<p->d<<endl;intrav(p->rchild);}return 0;}template <class T>void BS_Tree<T>::insert_BS_Tree(T x){BSnode<T> *p,*q;p=new BSnode<T>;p->d=x;p->lchild=NULL;p->rchild=NULL;q=BT;if(q==NULL) BT=p;else{while((q->lchild!=p)&&(q->rchild!=p)){if(x<q->d){if(q->lchild!=NULL) q=q->lchild;else q->lchild=p;}else{if(q->rchild!=NULL) q=q->rchild;else q->rchild=p;}}}return;}template <class T>int BS_Tree<T>::delete_BS_Tree(T x){BSnode<T> *p,*q,*t,*s;int flag;p=BT;q=NULL;flag=0;while((p!=NULL)&&(flag==0)){if(p->d==x) flag=1;else if(x<p->d){q=p;p=p->lchild;}else{q=p;p=p->rchild;}}if(p==NULL){cout<<"not found"<<endl; return flag;}flag=1;if((p->lchild==NULL)&&(p->rchild==NULL)){if(p==BT) BT=NULL;else if(p==q->lchild) q->lchild=NULL;else q->rchild=NULL;delete p;}else if((p->lchild==NULL)||(p->rchild==NULL)){if(p==BT){if(p->lchild==NULL) BT=p->rchild;else BT=p->lchild;}else{if((p==q->lchild)&&(p->lchild!=NULL))q->lchild=p->lchild;else if((p==q->lchild)&&(p->rchild!=NULL))q->lchild=p->rchild;else if((p==q->rchild)&&(p->lchild!=NULL))q->rchild=p->lchild;elseq->rchild=p->rchild;}delete p;}else{t=p;s=t->lchild;while(s->rchild!=NULL){t=s;s=s->rchild;}p->d=s->d;if(t==p)p->lchild=s->lchild;else t->rchild=s->lchild;delete s;}return flag;}template <class T>BSnode<T>*BS_Tree<T>::serch_BS_Tree(T x){BSnode<T> *p=NULL;int flag;p=BT;flag=0;while((p!=NULL)&&(flag==0)){if(p->d==x) flag=1;else if(x<p->d) p=p->lchild;else p=p->rchild;}if(p==NULL){cout<<"not found";return p;}return p;}
具体调用这些操作的实例,看下面:

#include"BS_Tree.h"int main(){int k;int d[12]={04,18,13,79,33,45,06,23,35,12,34,76};BS_Tree<int> b;for(k=0;k<12;k++)b.insert_BS_Tree(d[k]);cout<<"the sort element:"<<endl;b.intrav_BS_Tree();for(k=0;k<6;k++)b.delete_BS_Tree(d[k]);cout<<"after the delete:"<<endl;b.intrav_BS_Tree();cout<<"the serch result:"<<endl;for(k=0;k<12;k++)cout<<b.serch_BS_Tree(d[k])<<endl;return 0;}
具体,最后的实验结果,我就不多说了,不过,关于,代码中的一些操作说几点:

关于中序遍历:

这个在前面的二叉树遍历中就讲过了,而这里,二叉排序树的排序,就是,这个中序,所以很简单不多说。

关于插入:

一个二叉树的建立,就是把节点一个一个插入就完成了。

千万记住:插入的每个点,其实,,,都是在叶子结点处,不信,你自己看看。明白了这个,插入就ok了

关于删除:

这个就比较麻烦了,因为情况有3种,这个和你是二叉树是有关系的,那么:

1.自己是叶子结点

好了,删除呗,没啥好商量的,它的父亲处理一下,令为NULL就好了

2.自己有一个单子树

那么它的孩子们就跟它的父亲,父亲在爷爷的左边,孙子就去左边,父亲在爷爷的右边,孙子就去爷爷的右边,不管你是你父亲的左边还是右边

3.自己有2个孩子

那这就比较麻烦了,我给出的这个例子的思路是,判断这个结点的左结点的右子树空吗?空,那就把你孩子的值,给你,然后再把你挤掉,否则,那就找左结点的右子树的右子树,直到这个点是叶子节点,此时,让这个结点代替你,这个结点的孩子代替它。

也许说的有点乱,直接点就是说,让这个点的要么前驱,要么后继,代替它,然后保持二叉树的完整。

至于实现,那么就有很多的具体办法了。仁者见仁 。


原创粉丝点击