_DataStructure_C_Impl:二叉排序树的查找

#include<stdio.h>
#include<stdlib.h>

typedef int KeyType;
//元素的定义
typedef struct{
	KeyType key;
}DataType;
//二叉排序树的类型定义
typedef struct Node{
	DataType data;
	struct Node *lchild,*rchild;
}BiTreeNode,*BiTree;
//二叉排序树的查找,如果找到元素x,则返回指向结点的指针,否则返回NULL
BiTree BSTSearch(BiTree T,DataType x){
	BiTreeNode *p;
	if(T!=NULL){
		p=T;
		while(p!=NULL){		//如果二叉排序树不为空
			if(p->data.key==x.key)	//如果找到,则返回指向该结点的指针
				return p;
			else if(p->data.key>x.key)	//如果关键字小于p指向的结点的值,则在左子树中查找
				p=p->lchild;
			else
				p=p->rchild;	//如果关键字大于p指向的结点的值,则在右子树中查找
		}
	}
	return NULL;
}
//二叉排序树的插入操作,如果树中不存在元素x,则将x插入到正确的位置并返回1,否则返回0
int BSTInsert(BiTree *T,DataType x){
	BiTreeNode *p,*cur,*parent=NULL;
	cur=*T;
	while(cur!=NULL){
		if(cur->data.key==x.key)	//如果二叉树中存在元素为x的结点,则返回0
			return 0;
		parent=cur;		//parent指向cur的前驱结点
		if(x.key<cur->data.key)		//如果关键字小于p指向的结点的值,则在左子树中查找
			cur=cur->lchild;
		else						//如果关键字大于p指向的结点的值,则在右子树中查找
			cur=cur->rchild;
	}
	p=(BiTreeNode*)malloc(sizeof(BiTreeNode));	//生成结点
	if(!p)
		exit(-1);
	p->data=x;
	p->lchild=NULL;
	p->rchild=NULL;
	if(!parent)				//如果二叉树为空,则第一结点成为根结点
		*T=p;
	else if(x.key<parent->data.key)	//如果关键字小于parent指向的结点,则将x成为parent的左孩子
		parent->lchild=p;
	else							//如果关键字大于parent指向的结点,则将x成为parent的右孩子
		parent->rchild=p;
	return 1;
}
//从二叉排序树中删除结点s,并使该二叉排序树性质不变
void DeleteNode(BiTree *s){
	BiTree q,x,y;
	if(!(*s)->rchild){			//如果s的右子树为空,则使s的左子树成为被删结点双亲结点的左子树
		q=*s;
		*s=(*s)->lchild;
		free(q);
	}else if(!(*s)->lchild){	//如果s的左子树为空,则使s的右子树成为被删结点双亲结点的左子树
		q=*s;
		*s=(*s)->rchild;
		free(q);
	}else{	//*如果s的左、右子树都存在,则使s的直接前驱结点代替s,并使其直接前驱结点的左子树成为其双亲结点的右子树结点
		x=*s;
		y=(*s)->lchild;
		while(y->rchild){	//查找s的直接前驱结点,y为s的直接前驱结点,x为y的双亲结点
			x=y;
			y=y->rchild;
		}
		(*s)->data=y->data;	//结点s被y取代
		if(x!=*s)	//如果结点s的左孩子结点存在右子树
			x->rchild=y->lchild;	//使y的左子树成为x的右子树
		else		//如果结点s的左孩子结点不存在右子树
			x->lchild=y->lchild;	//使y的左子树成为x的左子树
		free(y);
	}
}
//在二叉排序树T中存在值为x的数据元素时,删除该数据元素结点,并返回1,否则返回0
int BSTDelete(BiTree *T,DataType x){
	if(!*T)		//如果不存在值为x的数据元素,则返回0
		return 0;
	else{
		if(x.key==(*T)->data.key)		//如果找到值为x的数据元素,则删除该结点
			DeleteNode(T);
		else if((*T)->data.key>x.key)	//如果当前元素值大于x的值,则在该结点的左子树中查找并删除之
			BSTDelete(&(*T)->lchild,x);
		else							//如果当前元素值小于x的值,则在该结点的右子树中查找并删除之
			BSTDelete(&(*T)->rchild,x);
	}
}
//中序遍历二叉排序的递归实现
void InOrderTraverse(BiTree T){
	if(T)								/*如果二叉排序树不为空*/
	{
		InOrderTraverse(T->lchild);			/*中序遍历左子树*/
		printf("%4d",T->data); 				/*访问根结点*/
		InOrderTraverse(T->rchild); 		/*中序遍历右子树*/
	}
}
void main(){
	BiTree T=NULL,p;
	DataType table[]={37,32,35,62,82,95,73,12,5};
	int n=sizeof(table)/sizeof(table[0]);
	DataType x={73},s={32};
	int i;
	for(i=0;i<n;i++)
		BSTInsert(&T,table[i]);
	printf("中序遍历二叉排序树得到的序列为:\n");
	InOrderTraverse(T);
	p=BSTSearch(T,x);
	if(p!=NULL)
		printf("\n二叉排序树查找,关键字%d存在\n",x.key);
	else
		printf("查找失败!\n");
	BSTDelete(&T,s);
	printf("删除元素%d后,中序遍历二叉排序树得到的序列为:\n",s.key);
	InOrderTraverse(T);
	printf("\n");
	system("pause");
}
/*
//平衡二叉排序树
//当平衡二叉排序树失去平衡时,对LL型的调整
BSTree b;
b=p->lchild;//p是根结点,b指向p的左子树的根结点
p->lchild=b->rchild;//将b的右子树作为p的左子树
b->rchild=p;//将p作为b的右子树,新树以b为根结点
p->bf=b->bf=0;//修改平衡因子
//当平衡二叉排序树失去平衡时,对LR(LRL)型的调整
BSTree b,c;//p为根结点,b为p的左子树的根结点,c为b的右子树的根结点
b=p->lchild;//b为p的左子树的根结点
c=b->rchild;//c为b的右子树的根结点
b->rchild=c->lchild;//c的左子树作为b的右子树
p->lchild=c->rchild;//c的右子树作为p的左子树
c->lchild=b;//b作为c的左子树
c->rchild=p;//p作为c的右子树,新树以c为根结点
//修改平衡因子
p->bf=-1;
b->bf=0;
c->bf=0;
//当平衡二叉排序树失去平衡时,对RL(RLR)型的调整
BSTree b,c;//p为根结点,b为p的右子树的根结点,c为b的左子树的根结点
b=p->rchild;//b为p的右子树的根结点
c=b->lchild;//c为b的左子树的根结点
b->lchild=c->rchild;//c的右子树作为b的左子树
p->rchild=c->lchild;//c的左子树作为p的右子树
c->lchild=p;//p作为c的左子树
c->rchild=b;//b作为c的右子树,新树以c为根结点
//修改平衡因子
p->bf=1;
b->bf=0;
b->bf=0;
//当平衡二叉排序树失去平衡时,对RR型的调整
BSTree b;
b=p->rchild;//p是根结点,b指向p的右子树的根结点
p->rchild=b->lchild;//将b的左子树作为p的右子树
b->lchild=p;//将p作为b的左子树,新树以b为根结点
//修改平衡因子
p->bf=0;
b->bf=0;
//B-树.B+树的动态查找
//B-树的类型定义
#define m 4  //B-树的阶数
typedef struct BTNdoe{
	int keynum;	//每个结点中的关键字个数
	struct BTNode *parent;//指向双亲结点
	KeyType data[m+1];//结点中关键字信息
	struct BTNode *ptr[m+1];//指针向量
}BTNode,*BTree;
*/

版权声明:本文为博主原创文章,未经博主允许不得转载|Copyright ©2011-2015,Supernatural, All Rights Reserved.

时间: 2024-08-01 16:30:45

_DataStructure_C_Impl:二叉排序树的查找的相关文章

重温数据结构:二叉排序树的查找、插入、删除

读完本文你将了解到: 什么是二叉排序树 Binary Sort Tree BST 二叉排序树的关键操作 查找 插入 删除 运行代码测试 一道面试题 总结 Thanks 我们知道,二分查找可以缩短查找的时间,但是有个要求就是 查找的数据必须是有序的.每次查找.操作时都要维护一个有序的数据集,于是有了二叉排序树这个概念. 上篇文章 我们介绍了 二叉树 的概念,二叉树有左右子树之分,想必在区分左右子树时有一定的规则. 现在我们来介绍二叉树的一种特殊形式 - 二叉排序树,了解它的区分策略及常用操作. 什

查找[2]二叉排序树以及查找

1 #include "iostream" 2 #include "iomanip" 3 #include "time.h" 4 using namespace std; 5 6 #define num 13 7 8 struct Bnode{ 9 int data; 10 Bnode *lchild; 11 Bnode *rchild; 12 }; 13 14 /* 15 *将指针S所指的结点插入到二叉排序树T中 16 */ 17 void i

基于二叉排序树的查找

导论:首先,沿着二分查找的思路,我们构造一种二叉树来查找,这种二叉树的左子树结点都小于根节点,右子树节点都大于根节点,这样一来,所有结点算是都排好序了,接下来就可以查找 基于二叉排序树的查找 一.二叉排序树的定义 所谓二叉排序树是一个什么样的东西,我们得弄清楚,以下是二叉排序树的定义: 1.若它的左子树非空,则左子树上所有节点的值都小于根节点的值 2.若它的右子树非空,则右子树上所有结点的值都大于根节点的值 3.它的左子树和右子树也是一颗二叉排序树 有了定义,很多东西就都会显而易见了: 1.二叉

BST二叉排序树的查找和删除的完整C代码

二叉排序树的查找算法 假定二叉排序树的根节点指针为root,给定的关键字值为key,则查找算法可描述为: 置初值:p = root : 如果 key = p -> data ,则查找成功,算法结束: 否则,如果key < p->data ,而且 p 的左子树非空,则将 p 的左子树根送 p ,转步骤 2 :否则,查找失败,算法结束: 否则,如果 key > p->data ,而且 p 的右子树非空,则将 p 的右子树根送 p ,转步骤 2 :否则,查找失败,算法结束. //B

二叉排序树的查找、插入和删除

1.      二叉排序树 二叉排序树(Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有结点值相同的结点. 二叉排序树又称二叉查找树(Binary Search Tree),亦称二叉搜索树.通常采用二叉链表作为二叉排序树的存储结构.中序遍历二叉排序树可以得到关键字有序的序列,即一个无序序

【数据结构】简单谈一谈二分法和二叉排序树BST查找的比较

二分法查找: 『在有序数组的基础上通过折半方法不断缩小查找范围,直至命中或者查询失败.』 二分法的存储要求:要求顺序存储,以便于根据下标随机访问 二分法的时间效率:O(Log(n)) 二分法的空间效率:原地查询 O(1) 二分法对应的搜索树是确定的. 二叉排序树查找: 『借助二叉排序树进行搜索,但因为所建立的树本身不一定是轴对称的,所以每次比较并不能确保减小一半范围.』 二叉树的存储要求:需要树形结构,相比顺序存储需要占用更多的空间,但也有链接型数据结构灵活可拓展的有点. 二叉排序树查找的时间复

二叉排序树的查找、插入、删除

直接上代码了 struct BTNode { int value; BTNode *lchild, *rchild; }; BTNode* recursiveSearch(BTNode *T, int value) { if (T == NULL || value == T->value) return T; if (value < T->value) return recursiveSearch(T->lchild, value); else return recursiveSe

查找系列之二叉排序树

二叉排序树的创建.查询.插入与删除 一.简述二叉排序树的思想: 动态查找表中主要有二叉树结构和树结构两种,而二叉树结构分为二叉排序树和平衡二叉树,树结构分为B-树和B+树等. 二叉排序树可以是一颗空树二叉排序树的性质:二叉排序树上的节点满足左子树<父节点<右子树 也就是说二叉排序树必须有顺序,且满足左子树<父节点<右子树 二.构建二叉排序树 创建二叉排序树通常我们用链式存储结构的节点作为存储单位:如 typedef struct Node{ TypeData data; struc

二叉排序树(概念,查找,插入,删除)

查找基本概念 查找表:由同一类型的数据元素构成的集合.对查找表的常用操作:查询元素是否存在.查询元素属性.插入一个数据元素.删除一个数据元素. 查找:也叫检索,是根据给定的某个值,在表中确定一个关键字等于给定值的数据元素. 关键字:可以标识一个数据元素的某个数据项. 主关键字:可以唯一地识别一个数据元素的关键字. 静态查找表:只进行查询某元素在表中与否或检索某元素的各种属性操作的表. 动态查找表:查找时同时进行插入表中无的元素或删除表中有的某元素的表. 二叉排序树 定义:二叉排序树(Binary