数据结构查找

#include <iostream>
using namespace std;

//顺序表查找 带哨兵
int sequential(int*a,int n,int key){
	//a代表数组,n代表元素个数,key代表关键字
	a[0]=key;int i;
	for(i=n;a[i]!=a[0];i--);//从后往前,找不到则return 0 
	return i;
} 
//-----------------------------------------------------------------------
//二分有序查找 
int binary(int*a,int n,int key){
	int low,high,mid;
	low=1;high=n;//从两端开始 
	while(low<=high){//循环结束条件为low>high 
		mid=(low+high)/2;//平分区间 
		if(key<a[mid])
		high=mid-1;
		else if(key>a[mid])
		low=mid+1;
		else return mid;
		//当mid==high了再进入一次循环输出 
	}
	return 0;
}
//--------------------------------------------------------------------------
//二叉排序树
 typedef struct tree{
 	int data;
 	struct tree*lchild,*rchild;//左右孩子 左边小于根右边大于根 
 }*ptree;
 //查找 
 int searchbst(ptree t,int key,ptree f,ptree&point){//需要改变传入参数则传指针或者引用 
 	if(!t){//如果找不到 
 		point=f;//point指向最后一个结点 
 		return 0;
	 }
	 else if(key==t->data){// 如果找到了 
	 	point=t;
	 	return 1;
	 }
	 //如果比结点小 
	 else if(key<t->data)
	 return searchbst(t->lchild,key,t,point);
	 else//如果比结点大 
	 return searchbst(t->rchild,key,t,point);
 }
 //插入
 int insertbst(ptree&t,int key){
 	ptree p,s;
 	if(!searchbst(t,key,NULL,p)){//如果找不到 
 		s=new tree;//建立新节点 
 		s->data=key;
 		s->lchild=NULL;
 		s->rchild=NULL;
 		if(!p)//如果p指向空 
 		t=s;
 		else if(p->data<key)//如果p的数据比key小 
 		p->rchild=s;
 		else
 		p->lchild=s;
 		return 1;
	 }
 	return 0;
 }
  //删除
  int delete_(ptree&t){//删除t结点并重接 
  	ptree q,s;
  	if(!t->lchild){// 如果左孩子不存在 
  		q=t;t=t->rchild;free(q);//将右孩子接上,释放节点 
	  }
	else if(!t->rchild){
		q=t;t=t->lchild;free(q); 
	}
	else{//如果左右孩子都存在,意味着不能简单重接 
		q=t;s=t->lchild;//q从t出发,s从t左孩子出发 
		while(s->rchild){//一路向右找 找到最后一个右节点 
			q=s;s=s->rchild;
		}//q代表最后一个右节点的父母 
		t->data=s->data;//将s的值覆盖t的值 
		if(q!=t){//如果进入了循环 那么将s结点的左子树(s无右子树)接在q的右子树上 
			q->rchild=s->lchild;
		}
		//如果没有进入循环 则q和t相等 此时将s结点的左子树(s无右子树)接在q的左子树上
		else q->lchild=s->lchild;
		free(s);//释放s结点 
	}
  } 
  
  int deletebst(ptree&t,int key){//类比查找 
  	if(!t){//如果找不到 
 		return 0;
	 }
	 else if(key==t->data){// 如果找到了 
	 	return delete_(t);
	 }
	 //如果比结点小 
	 else if(key<t->data)
	 return deletebst(t->lchild,key);
	 else//如果比结点大 
	 return deletebst(t->rchild,key);
  } 
 
 void show(ptree&t){
 	if(!t)return;
 	cout<<t->data<<endl;
 	show(t->lchild);
 	show(t->rchild);
 }
 //-----------------------------------------------------------------------------
 //平衡二叉树
  typedef struct bitree{
 	int data;
 	int bf;
 	struct bitree*lchild,*rchild;//左右孩子 左边小于根右边大于根 
 }*pbitree;
 //右旋 以t为根 
 void right_(pbitree&t){
 	pbitree l;
 	l=t->lchild;//令l为t的左孩子 即为新的根节点 
 	t->lchild=l->rchild;//令l的右孩子为t的左孩子 
 	l->rchild=t;//将t接在l右边 
 	t=l;//更新t 
 }
 // 左旋 以t为根
  void left_(pbitree&t){
 	pbitree r;
 	r=t->rchild;//令r为t的右孩子 即为新的根节点 
 	t->rchild=r->lchild;//令r的左孩子为t的右孩子 
 	r->lchild=t;//将t接在r左边 
 	t=r;//更新t 
 }
 //左平衡
 void leftbalance(pbitree&t){//t第一次不平衡 
 	pbitree l,lr;
 	l=t->lchild;//l为t左孩子 
 	switch(l->bf){//检查l的平衡度(l平衡度不可能为0 否则t不是第一次) 
 		case 1://右旋即可 
 		t->bf=l->bf=0;//令t和l的平衡度为0 
 		right_(t);
 		break;
 		case -1://需要双旋
		lr=l->rchild; //lr为t左节点的右节点 
		switch(lr->bf){//如分析 
			case 1:
				t->bf=-1;
				l->bf=0;
				break;
			case 0:
				t->bf=l->bf=0;
				break;
			case -1:
				t->bf=0;
				l->bf=1;
				break;
		} 
 		lr->bf=0;//此时lr为根节点 
 		left_(t->lchild);
 		right_(t);
	 }
}
//右平衡
void rightbalance(pbitree&t){
	pbitree r,rl;
 	r=t->rchild;
 	switch(r->bf){
 		case -1:
 		t->bf=r->bf=0; 
 		left_(t);
 		break;
 		case 1:
		rl=r->lchild;  
		switch(rl->bf){
			case -1:
				t->bf=1;
				r->bf=0;
				break;
			case 0:
				t->bf=r->bf=0;
				break;
			case 1:
				t->bf=0;
				r->bf=-1;
				break;
		} 
 		rl->bf=0;
 		right_(t->rchild);
 		left_(t);
} 	
 }
 //
 int insertavl(pbitree&t,int e,int*taller){
 	if(!t){//如果t不存在 
 		t=new bitree;
 		t->data=e;
 		t->lchild=t->rchild=NULL;
 		t->bf=0;
 		*taller=true;//代表需要判断平衡度,长叶子 
	 }
	 else{//如果找到了 
	 	if(e==t->data){
	 		*taller=false;//代表不需要长叶子 
	 		return false;
		 }
		 if(e<t->data){//如果发现小于 则在左子树里找 
		 	if(!insertavl(t->lchild,e,taller))//如果没有插入 
		 	return false;
		 	if(*taller){//有新增结点的话 
		 		switch(t->bf){//判断平衡度 
		 			case 1://原本左子树高 则左平衡 
		 				leftbalance(t);
		 				*taller=false;
		 				break;
		 			case 0://原本一样高 左边增高 
		 				t->bf=1;
		 				*taller=true;
		 				break;
		 			case -1://原本右子树高 则右平衡 
		 				t->bf=0;
		 				*taller=false;
		 				break;
				 }
			 }
		 }
		 else{//与上同理 
		 	if(!insertavl(t->rchild,e,taller))
		 	return false;
		 	if(*taller){
		 		switch(t->bf){
		 			case 1:
		 				t->bf=0;
		 				*taller=false;
		 				break;
		 			case 0:
		 				t->bf=-1;
		 				*taller=true;
		 				break;
		 			case -1:
		 				rightbalance(t);
		 				*taller=false;
		 				break;
				 }
			 }
		 }
		 return true;
	 }
 }
 
  void show_(pbitree&t){
 	if(!t)return;
 	cout<<t->data<<endl;
 	show_(t->lchild);
 	show_(t->rchild);
 }
  
 int main(){
 	pbitree t,point;
 	int a[]={100,3,101,10,6,12,11};
 	int taller;
 	for(int i=0;i<=6;i++)
    insertavl(t,a[i],&taller);
 	show_(t);
 	
 	
 	
 	
 	return 0;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值