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

动态查找表之二叉排序树(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;
}

操作结果如下:


  • 6
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
二叉排序树(Binary Search Tree,简称BST)是一种特殊的二叉树,它的左子树中所有节点的值都小于根节点的值,右子树中所有节点的值都大于根节点的值。因此,通过比较节点值的大小关系,可以在二叉排序树中进行高效的查找插入删除操作。 创建二叉排序树: 1. 对于空树,直接将新节点作为根节点。 2. 对于非空树,从根节点开始比较新节点的值与当前节点的值的大小关系,如果小于当前节点的值,则将新节点插入到当前节点的左子树中;如果大于当前节点的值,则将新节点插入到当前节点的右子树中。 查找二叉排序树: 从根节点开始比较要查找的值与当前节点的值的大小关系,如果相等则返回当前节点;如果小于当前节点的值,则在当前节点的左子树中查找;如果大于当前节点的值,则在当前节点的右子树中查找。如果遍历到叶子节点仍未找到,则说明要查找的值不存在于二叉排序树中。 插入节点: 从根节点开始比较要插入的节点的值与当前节点的值的大小关系,如果小于当前节点的值,则在当前节点的左子树中插入;如果大于当前节点的值,则在当前节点的右子树中插入。如果遍历到叶子节点仍未找到合适的位置,则将新节点作为当前节点的左子节点或右子节点。 删除节点: 1. 如果要删除的节点是叶子节点,则直接删除。 2. 如果要删除的节点只有一个子节点,则将其子节点替换为要删除的节点。 3. 如果要删除的节点有两个子节点,则找到其右子树中的最小节点(或左子树中的最大节点),将其值替换为要删除的节点的值,然后删除最小节点。 以上就是二叉排序树创建查找插入删除操作的基本思路。需要注意的是,在实现过程中需要考虑到各种边界情况和特殊情况,以保证程序的正确性和鲁棒性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值