二叉搜索树

本文深入探讨了二叉搜索树的定义、优势及其在查找、插入、删除操作上的高效实现,通过具体代码示例展示了如何在C++中构建并操作二叉搜索树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是二叉搜索树

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树), 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

2.为啥要学二叉搜索树呢?

大家都对二分查找有一定的了解吧。里面每一个元素是有序的,查找的时间复杂度是O(log(n))的。效率很高,而二叉搜索树按照中序遍历也是有序的,而且 查找、插入、删除的时间复杂度都是O(log(n))的。而二分查找插入、删除元素困难,二叉搜索树不知道比二分查找法高到哪里去了(滑稽)。

3.二叉搜索树的实现

在这里插入图片描述

需要先根据上图创建树,下面有完整代码。

二叉搜索树的查找:

bool find_node(BTree *root,int n)   //n为要查找的值
{
	if(root==NULL)                        //不存在
		return false;
	else if(root->value==n)               //找到了
		return true;
	else if(root->value<n)                  //当前访问的节点比要查找的小,去右节点查找
		return find_node(root->rchild,n);
	else if(root->value>n)                  //当前访问的节点比要查找的大,去左节点查找
		return find_node(root->lchild,n);

}

二叉搜索树的插入:
插入节点和查找节点很相似,插入只是在为NULL的地方直接添加节点就可以了。
PS:插入一个节点时要注意二叉搜索树不允许重复关键码,插入的时候需要判断一下。

bool insert_node(BTree * &root,int n)   //n为要插入的值
{
	if(root!=NULL && root->value==n)    //如果已经存在该节点,插入失败
		return false;
	if(root==NULL)                      //在这个位置插入
	{
		root=new BTree;
		root->value = n;
		root->lchild=NULL;
		root->rchild=NULL;
		return true;
	}
	else if(root->value<n)
		return insert_node(root->rchild,n);
	else if(root->value>n)
		return insert_node(root->lchild,n);
}

二叉搜索树的删除:
(1)需要找到要删除的节点
(2)如果被删除节点的左节点为空,直接可以把其右节点挂接上去。如果被删除节点的右节点为空,把其左节点挂接上去。如果左右节点都为空,随便挂接左右节点都可以。如果左右节点都不为空,则需要在被删除节点的右子树里,找到值最小的那个节点node_min,因为node_min的值最小,所以node_min的左节点为空,直接把node_min的右节点挂接上去。然后把node_min的值赋值给被删除的节点。

贴代码


BTree * delete_min(BTree * &root)    //参数为指针的引用
{
	if(root->lchild!=NULL)                     //如果左孩子不为空,继续寻找
		return delete_min(root->lchild);
	else                                        //左孩子为空
	{
		BTree * temp=root;
		root=root->rchild;
		return temp;
	}
}

void delete_node(BTree * &root,int n)        //n为要删除的值
{
	if(root==NULL)                      //找不到节点
		cout<<"is not in tree"<<endl;
	else if(root->value>n)
		delete_node(root->lchild,n);
	else if(root->value<n)
		delete_node(root->rchild,n);
	else                                  //找到该节点,进行删除操作
	{    
		BTree * temp = root;
		if(root->lchild==NULL)            //左孩子为空,挂接右孩子
			root=root->rchild;
		else if(root->rchild==NULL)        //右孩子为空,挂接左孩子
			root=root->lchild;
		else                              //都不为空
		{
			temp=delete_min(root->rchild);
			root->value=temp->value;
			
		}
		delete temp;
	}
}

下面贴个完整代码

#include<iostream>
using namespace std;

struct BTree
{
	int value;
	BTree *lchild;
	BTree *rchild;
};

BTree * Created(int *num,int &index)          //根据数组创建二叉树
{
	if(num[index]==0)
		return NULL;
	else
	{
		BTree *root=new BTree;
		root->value=num[index];
		root->lchild=Created(num,++index);
		root->rchild=Created(num,++index);
		return root;
	}
}
bool find_node(BTree *root,int n)     //n为要查找的值
{
	if(root==NULL)                        //不存在
		return false;
	else if(root->value==n)               //找到了
		return true;
	else if(root->value<n)                  //当前访问的节点比要查找的小,去右节点查找
		return find_node(root->rchild,n);
	else if(root->value>n)                  //当前访问的节点比要查找的大,去左节点查找
		return find_node(root->lchild,n);

}
bool insert_node(BTree * &root,int n)    //n为要插入的值
{
	if(root!=NULL && root->value==n)    //如果已经存在该节点,插入失败
		return false;
	if(root==NULL)                      //在这个位置插入
	{
		root=new BTree;
		root->value = n;
		root->lchild=NULL;
		root->rchild=NULL;
		return true;
	}
	else if(root->value<n)
		return insert_node(root->rchild,n);
	else if(root->value>n)
		return insert_node(root->lchild,n);
}
void in_print(BTree *root)               //中序遍历
{
	if(root==NULL)
		return ;
	in_print(root->lchild);
	cout<<root->value<<" ";
	in_print(root->rchild);
}
BTree * delete_min(BTree * &root)    //指针的引用
{
	if(root->lchild!=NULL)                     //如果左孩子不为空,继续寻找
		return delete_min(root->lchild);
	else                                        //左孩子为空
	{
		BTree * temp=root;
		root=root->rchild;
		return temp;
	}
}

void delete_node(BTree * &root,int n)    //n为要删除的值
{
	if(root==NULL)                      //找不到节点
		cout<<"is not in tree"<<endl;
	else if(root->value>n)
		delete_node(root->lchild,n);
	else if(root->value<n)
		delete_node(root->rchild,n);
	else                                  //找到该节点,进行删除操作
	{    
		BTree * temp = root;
		if(root->lchild==NULL)            //左孩子为空,挂接右孩子
			root=root->rchild;
		else if(root->rchild==NULL)        //右孩子为空,挂接左孩子
			root=root->lchild;
		else                              //都不为空
		{
			temp=delete_min(root->rchild);
			root->value=temp->value;
			
		}
		delete temp;
	}
}
void print(BTree *root,int h)           //树形打印
{
	if(root!=NULL)
	{
		print(root->rchild,h+1);
		for(int i=0;i<h;i++)
			cout<<"     ";
		cout<<root->value;
		print(root->lchild,h+1);
	}
	cout<<endl;
}
int main()
{
	int h;
	int num[]={35,17,15,0,0,18,0,22,0,0,60,51,0,0,88,0,93,0,0};
	BTree *root=NULL;
	int index=0;
	root=Created(num,index); 	
	cout<<"初始二叉树"<<endl;
	print(root,0);             
	
	cout<<"输入要查找的数字"<<endl;
	int find_num;
	cin>>find_num;
	if( find_node(root,find_num))
		cout<<"查找成功"<<endl;
	else 
		cout<<"查找失败"<<endl;

	cout<<"请输入要插入的数字"<<endl;
	int insert_num;
	cin>>insert_num;
	if( insert_node(root,insert_num))
		cout<<"插入成功"<<endl;
	else
		cout<<"已经存在该节点"<<endl;
	print(root,0);

	cout<<"请输入要删除的数字"<<endl;
	int delete_num;
	cin>>delete_num;
	delete_node(root,delete_num);
	print(root,0);
	return 0;
}

运行结果:
测试查找
在这里插入图片描述

测试插入
在这里插入图片描述

删除测试
在这里插入图片描述

PS:本人小白,如有错误欢迎指出 q(≧▽≦q)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值