二叉搜索树(BST):创建,插入,删除

属性:1.每一个节点都带有唯一一个关键字

         2.左节点比父节点小,右节点比父节点大,左节点是左子树上所有的节点,右节点是右子树上所有的节点

        3.任何一个子树依旧是一个二叉搜索树

        4.中序遍历打印的值是有序排列的

我们来具体实现一个二叉搜索树,下面是代码

#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
struct bstTree {
	int val;
	bstTree* left;
	bstTree* right;
};

//定义往二叉搜索树BST插入节点的函数
void insert(bstTree** T, int data)//为什么要传二级指针呢?因为我们要改变指针中存放的地址,改变值要传二级指针
{
	//*T指向NULL
	if (*T == NULL)
	{
		bstTree* node = new bstTree();//申请一个新的节点
		node->val = data;
		node->left = NULL;
		node->right = NULL;
		*T = node;
	}
	else {
		if ((*T)->val>data)
		{
			//要插入的节点小于当前指针指向的节点
			//要插入的节点要放到当前节点的左子树
			insert(&((*T)->left), data);
		}
		else {
			//要插入的节点大于当前指针指向的节点
			//要插入的节点要放到当前节点的右子树
			insert(&((*T)->right), data);
		}
	}
}
//中序遍历BST树
void InorderTree(bstTree* T)
{
	if (T == NULL)
	{
		return;
	}
	else {
		InorderTree(T->left);
		cout << T->val << " ";
		InorderTree(T->right);
	}
}
int main() {
	//定义空树
	bstTree* T = NULL;
	int data;
	//输入10个数字
	for (int i = 0; i < 10; i++)
	{
		cout << "请输入数字: ";
		cin >> data;
		insert(&T, data);
	}
	cout << endl;
	InorderTree(T);
	cout << endl;
	system("pause");
	return 0;
}

查找操作:在二叉搜索树来找到对应的节点

//查找二叉树中的节点
//递归
bstTree* search1(bstTree* T, int val)
{
	//val 是我们要找的值
	if (T == NULL)
	{
		return NULL;
	}
	else if (T->val > val)
	{
		return search1(T->left, val);
	}
	else if (T->val < val)
	{
		return search1(T->right, val);
	}
	else {
		return T;
	}
	return NULL;
}
//通过迭代的方式来找到val值
bstTree* search2(bstTree* T, int val)
{
	bstTree* cur = T;
	while (cur != NULL)
	{
		if (cur->val > val)
		{
			cur = cur->left;
		}
		else if (cur->val < val)
		{
			cur = cur->right;
		}
		else if (cur->val == val)
		{
			return cur;
		}
	}
	return NULL;
}

删除操作:

我们在二叉搜索树中进行删除操作,一共有三种情况

(1)第一种情况:删除的节点既没有左子树,又没有右子树,例如删除下面二叉搜索树中的2,4,13等节点,我们直接返回NULL就行

(2)第二种情况:删除的节点仅仅只有一个子树(可以是左子树也可以是右子树),我们直接将该节点删除即可,返回它的左子树和右子树就行了,就像删除上面树中的7节点

(3)第三种情况:删除节点既有左子树又有右子树,我们又两种处理方法,第一种:我们可以将右节点接到左子树的最右的叶节点上,第二种:我们可以将左节点街道右子树的最左的叶节点上

我们看看图:下面是我们将6节点删除,将右子树的节点接到了左子树最右边的节点上

那我们将左子树的节点接到右子树的最左节点上

我们看看代码

//定义删除二叉搜索树中的节点
bstTree* deleteNode(bstTree* T, int val)
{
	//如果是空树,返回NULL
	if (T == NULL)
		return NULL;
	if (T->val > val) {
		//要找的节点小于当前节点,那就递归删除左子树上 的节点
		T->left = deleteNode(T->left, val);
		return T;
	}
	else if (T->val < val) {
		//要找的节点大于当前节点,那就递归删除右子树上的节点
		T->right = deleteNode(T->right, val);
		return T;
	}
	else if (T->val == val) {
		//这时候要删除的节点有下面三种情况
		//1.要删除的节点没有左右子树
		if (T->left == NULL && T->right == NULL) {
			bstTree* Node = T;
			delete T;//因为申请的内存都是在堆区的,所以要用delete来释放掉内存
			Node = NULL;
			return Node;
		}
		//2.要删除的节点有左孩子,但是没有右孩子,就让左孩子来代替这个节点
		else if (T->right == NULL && T->left != NULL) {
			bstTree* Node = T->left;
			delete T;
			return Node;
		}
		//要删除的节点有右孩子,但没有左孩子,那就让右孩子来代替这个节点
		else if (T->right != NULL && T->left == NULL) {
			bstTree* Node = T->right;
			delete T;
			return Node;
		}
		//3.要删除的节点有左孩子又有右孩子,那就将右孩子节点加到左孩子中最大的节点的右孩子上
		else if (T->right != NULL && T->left != NULL) {
			//找到左节点中最大的节点
			bstTree* cur = T->left;
			while (cur->right != NULL)
			{
				cur = cur->left;
			}
			//将T的右子树加到左子树上的最大节点上
			cur->right = T->right;
			bstTree* Node = T->left;
			delete T;
			return Node;
		}
	}
	//没有找到要删除的节点
	return T;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值