动态查找表之二叉排序树(BST)的 创建、查找、插入与删除

原创 2015年07月06日 23:49:53

动态查找表之二叉排序树(BST)的 创建、查找、插入与删除

删除结点的相关操作(左右子树均为非空的删除结点的方法):


算法分析:


下面以实例来说明二叉排序树的创建、查找、插入和删除等相关操作;

如输入关键字序列(452437125493),然后对其进行相应的操作,程序如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct BiTNode
{
	int value;
	struct BiTNode *lchild,*rchild;
}*BiTree;

bool LT(int a,int b)  //LessThan小于
{
	if(a<b)
		return true;
	else
		return false;
}
/*
在根指针root所指向的二叉排序树中递归地查找其关键字等于data的数据元素,若查找成功,则指针p指向该数据元素结点,并返回true,
否则指针p指向查找路径上访问的最后一个结点并返回false指针,指针f指向root的双亲,其初始调用值NULL
*/
bool SearchBST(BiTree root,int data,BiTree f,BiTree &p)
{
	if(!root)
	{
		p=f;
		return false;
	}
	else if(data == root->value)   //查找成功
	{
		p=root;
		return true;
	}
	else if(data < root->value)  //在左子树继续查找
		return SearchBST(root->lchild,data,root,p);
	else if(data > root->value)  //在右子树继续查找
		return SearchBST(root->rchild,data,root,p);
}

//当二叉排序树root中不存在关键字等于data的数据元素时,插入data
inline void InsertBST(BiTree &root,int data)     //root为传引用指针
{  
	BiTree p,s;
	if(!SearchBST(root,data,NULL,p))    //查找不成功
	{
		s=(struct BiTNode *)malloc(sizeof(BiTNode));
		s->value=data;
		s->lchild=s->rchild=NULL;
		if(p==NULL)    //二叉排序树为空的时候,被插入结点*s为新的根结点
			root=s;
		else if(LT(data,p->value))           //被插结点*s为左孩子
			p->lchild=s;
		else           //被插结点*s为右孩子
			p->rchild=s;
	}
	return ;
}
void PreOrderTraverse(BiTree root)    //先序遍历
{
	if(root)
	{
		printf("%d ",root->value);
		PreOrderTraverse(root->lchild);
		PreOrderTraverse(root->rchild);
	}
}
void InOrderTraverse(BiTree root)    //中序遍历
{
	if(root)
	{
		InOrderTraverse(root->lchild);
		printf("%d ",root->value);
		InOrderTraverse(root->rchild);
	}
}
void PostOrderTraverse(BiTree root)    //后序遍历
{
	if(root)
	{
		PostOrderTraverse(root->lchild);
		PostOrderTraverse(root->rchild);
		printf("%d ",root->value);
	}
}
int Delete(BiTree &p){
	BiTree q,s;
    if(!p->rchild){ //右子树空的话只需重接它的左 
	   q = p; p = p->lchild; free(q);
	}
	else if (!p->lchild){   //左子树为空的话,只需重接它的右子树
	   q = p; p = p->rchild; free(q);
	}
    else{  //左右子树均不为空
	   q = p;  s = p->lchild;
	   while(s->rchild) {   //转左。然后向右走到尽头
	    q = s; s = s->rchild;
	   }
	   p->value = s->value;  //s指向被删除结点的前驱
	   if(q != p) {q->rchild = s->lchild;} //重接*q的右子树
	   else {q->lchild = s->lchild;} //重接*q的左子树
		delete s;
	}
	return true;
}
int DeleteBST(BiTree &T,int key)
{
	 if(!T) return false;
	 else{
	   if(key == T->value) return Delete(T);  //找到关键字为key的数据元素
	   else if(key < T->value) return DeleteBST(T->lchild,key);//关键字小于结点的话,即在左子树
	   else return DeleteBST(T->rchild,key); //关键字大于结点的话,即在右子树
	 }
}

int main(void)
{
	int i,a[101],n,data,findkey,menu,insertkey;
	BiTree root,pp;
	printf("二叉排序树的操作:\n");
    printf("                1:创建二叉排序树!\n");
    printf("                2:查找关键字!\n");
    printf("                3:插入关键字!\n");	
	printf("                4:删除关键字!\n");
	printf("                0:退出!\n");
	//输入结点的个数
	printf("请输入相应操作:");
	scanf("%d",&menu);
	while(!(menu>=0 && menu <= 4)){
	  printf("您的输入有问题,请重新输入:");
	  scanf("%d",&menu);
	}
	while(menu != 0){/////////////////////////////////////
		switch(menu){ ///////////////////////
		case 1:{ ///////////////////
	            printf("输入初始化结点的个数:");
                scanf("%d",&n);
				root=NULL;
				printf("输入各个结点的值:");
				for(i=1;i<=n;i++)
				{
					scanf("%d",&a[i]);
					InsertBST(root,a[i]);
				}
                printf("输出先序遍历结果:");
				PreOrderTraverse(root);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
				printf("输出后序遍历结果:");
				PostOrderTraverse(root);
				printf("\n");
				break;
			 }//////////////////////////////case
		case 2:{
			    printf("输入你要查找的关键字:");
				scanf("%d",&findkey);
				if(SearchBST(root,findkey,NULL,pp)){
				printf("查找成功!\n");
				}else{
				printf("查找失败!\n");
				}
				break;
			   }
        case 3:{
			    printf("请输入你插入的关键字:");
				scanf("%d",&insertkey);
				InsertBST(root,insertkey);
              	printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
			    break;
			   }
		case 4:{
			    printf("输入你想删除的关键字:");
				scanf("%d",&data);
				DeleteBST(root,data);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
				break;
			   }
		   /*
			while(scanf("%d",&n)!=EOF)
			{
				root=NULL;
     			printf("输入各个结点的值:");
				for(i=1;i<=n;i++)
				{
					scanf("%d",&a[i]);
					InsertBST(root,a[i]);
				}
				printf("输出先序遍历结果:");
				PreOrderTraverse(root);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
				printf("输出后序遍历结果:");
				PostOrderTraverse(root);
				printf("\n");
				printf("输入你要查找的关键字:");
				scanf("%d",&findkey);
				if(SearchBST(root,findkey,NULL,pp)){
				printf("查找成功!\n");
				}else{
				printf("查找失败!\n");
				}
         
				printf("输入你想删除的关键字:");
				scanf("%d",&data);
				DeleteBST(root,data);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);

			}*/
		} //////switch
	 printf("请继续输入相应操作:");
    	scanf("%d",&menu);
	}//while
	return 0;
}

操作结果如下:


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

查找算法总结之二(动态查找表)

查找树查找算法总结(二),动态查找表

静态查找表与动态查找表

一、静态查找表 1.顺序表查找 顺序查找(Sequential Search)又称为线性查找,是一种最简单的查找方法。 查找过程如下: 从线性表的一端开始顺序扫描线性表,依次将扫描到的...

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...

Radon变换入门matlab CT原理

http://hi.baidu.com/hi9394/blog/item/0d492b8bfd714700c8fc7aa9.html 简介 图像投影,就是说将图像在某一方向上做线性积分(或理解为累...

Intel系列处理器的三种工作模式

Intel系列处理器的三种工作模式 微机中常用的Intel系列微处理器的主要发展过程是:8080,8086/8088,80186, 80286,80386,80486,Pentium,Pen...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:动态查找表之二叉排序树(BST)的 创建、查找、插入与删除
举报原因:
原因补充:

(最多只允许输入30个字)