二叉排序树的实现和操作

先提几个问题,如下:

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;
		else
			q->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个孩子

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

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值