二叉搜索树(BST)

  1. 结构定义
#include <iostream>
#include <algorithm>
using namespace std;
/*二叉树结构定义*/
typedef struct TNode{
	int Data;
	TNode *Left;
	TNode *Right;
} * BinTree;
  1. 查找
/*递归查找*/
BinTree FindRecursive(BinTree BST, int x)
{
	if(!BST)	//如果是空树, 查找失败
		return NULL;	//递归到叶结点时, 还没有找到

	if(x > BST->Data)
		return FindRecursive(BST->Right, x);
	else if(x < BST->Data)
		return FindRecursive(BST->Left, x);
	else 	//找到了
		return BST;
}
/*迭代查找*/
BinTree FindIteration(BinTree BST, int x)
{
	while (BST)		//退出循环途径1
	{
		if(x > BST->Data)
			BST = BST->Right;
		else if(x < BST->Data)
			BST = BST->Left;
		else
			break;	//退出循环途径2
	}

	return BST;		//返回结点地址或NULL
}
//**********************************************

/*递归查找最小值*/
BinTree FindMinRecursive(BinTree BST)
{
	if(!BST)			//除非是空树
		return NULL;
	else if(!BST->Left)	//找到最小值
		return BST;
	else				//还有左孩子
		return FindMinRecursive(BST->Left);
}
/*迭代查找最小值*/
BinTree FindMinIteration(BinTree BST)
{
	if (BST)			   //如果树非空
		while (BST->Left) //直到找到最左端
			BST = BST->Left;
	return BST;
}
//**********************************************

/*递归查找最大值*/
BinTree FindMaxRecursive(BinTree BST)
{
	if (!BST) //除非是空树
		return NULL;
	else if (!BST->Right) //找到最大值
		return BST;
	else //还有右孩子
		return FindMaxRecursive(BST->Right);
}
/*迭代查找最大值*/
BinTree FindMaxIteration(BinTree BST)
{
	if(BST)	//如果树非空
		while (BST->Right)	//直到找到最右端
			BST = BST->Right;
	return BST;
}
  1. 插入
#include "binary_search_tree.h"

BinTree Insert(BinTree BST, int x)	//插入位置一定是叶结点, 递归算法
{
	if(!BST)	//如果BST为空, 即到了叶结点
	{
		BST = new TNode();
		BST->Data = x;
	}
	else
	{
		if(x < BST->Data)		//应该要插入左孩子
			BST->Left = Insert(BST->Left, x);
		else if(x > BST->Data)	//应该要插入右孩子
			BST->Right = Insert(BST->Right, x);
		//若x == BST->Data
		//什么也不做, 往下执行
	}
	return BST;	//返回的是插入了新元素后的原来的树的地址
}
  1. 删除
    分3总情况考虑:
    (1) 要删除的是叶结点
    最简单,直接删除
    在这里插入图片描述
    (2) 要删除的结点只有一个孩子结点
    也很简单,直接将删除结点的父亲指向删除结点的孩子
    在这里插入图片描述
    (3) 要删除的结点有两个孩子结点
    这是有两种选择:一种是取其右子树中的最小元素;另一种是取左子树的最大元素。通过算法将第三种情况转变为前两种情况
    在这里插入图片描述
    算法实现的主要步骤
    a. 查找,找到要删除的元素位置,如果没有找到,退出并表示没有改元素
    b. 判断,判断要删除的结点有几个孩子
    c. 删除,根据结点类型常用相应的删除算法
BinTree Delete(BinTree BST, int x)	//采用递归算法
{
	BinTree Tmp;
	if(!BST)
		cout << "No" << endl;
	else
	{
		if(x > BST->Data)
			BST->Right = Delete(BST->Right, x);
		else if(x < BST->Data)
			BST->Left = Delete(BST->Left, x);
		else	//找到要删除的元素后
		{
			if(BST->Left && BST->Right)
			{
				Tmp = FindMin(BST->Right);	//找右子树的最小值
				BST->Data = Tmp->Data;
				BST->Right = Delete(BST->Right, BST->Data);		//真正删除: 转变为删除叶结点或一个孩子的结点
			}
			else	//删除有1个或0个孩子的结点
			{
				Tmp = BST;
				if(!BST->Left)	//只有右孩子或无子结点
					BST = BST->Right;
				else
					BST = BST->Left;
				delete Tmp;
			}
		}
	}
	return BST;		//返回被删除好的原树
}

代码实现
binary_search_tree.h

#include <iostream>
#include <algorithm>
using namespace std;
/*二叉树结构定义*/
typedef struct TNode{
	int Data;
	TNode *Left;
	TNode *Right;
} * BinTree;

BinTree Insert(BinTree BST, int x) //插入位置一定是叶结点, 递归算法
{
	if (!BST) //如果BST为空, 即到了叶结点
	{
		BST = new TNode();
		BST->Data = x;
	}
	else
	{
		if (x < BST->Data) //应该要插入左孩子
			BST->Left = Insert(BST->Left, x);
		else if (x > BST->Data) //应该要插入右孩子
			BST->Right = Insert(BST->Right, x);
		//若x == BST->Data
		//什么也不做, 往下执行
	}
	return BST; //返回的是插入了新元素后的原来的树的地址
}
/*迭代查找*/
BinTree Find(BinTree BST, int x)
{
	while (BST) //退出循环途径1
	{
		if (x > BST->Data)
			BST = BST->Right;
		else if (x < BST->Data)
			BST = BST->Left;
		else
			break; //退出循环途径2
	}

	return BST; //返回结点地址或NULL
}
/*迭代查找最小值*/
BinTree FindMin(BinTree BST)
{
	if (BST)			  //如果树非空
		while (BST->Left) //直到找到最左端
			BST = BST->Left;
	return BST;
}
/*递归查找最大值*/
BinTree FindMax(BinTree BST)
{
	if (!BST) //除非是空树
		return NULL;
	else if (!BST->Right) //找到最大值
		return BST;
	else //还有右孩子
		return FindMax(BST->Right);
}
BinTree Delete(BinTree BST, int x) //采用递归算法
{
	BinTree Tmp;
	if (!BST)
		cout << "No" << endl;
	else
	{
		if (x > BST->Data)
			BST->Right = Delete(BST->Right, x);
		else if (x < BST->Data)
			BST->Left = Delete(BST->Left, x);
		else //找到要删除的元素后
		{
			if (BST->Left && BST->Right)
			{
				Tmp = FindMin(BST->Right); //找右子树的最小值
				BST->Data = Tmp->Data;
				BST->Right = Delete(BST->Right, BST->Data); //真正删除: 转变为删除叶结点或一个孩子的结点
			}
			else //删除有1个或0个孩子的结点
			{
				Tmp = BST;
				if (!BST->Left) //只有右孩子或无子结点
					BST = BST->Right;
				else
					BST = BST->Left;
				delete Tmp;
			}
		}
	}
	return BST; //返回被删除好的原树
}

main.cpp

#include "binary_search_tree.h"

//输出二叉搜索树的中序遍历
void Print(const BinTree BST)
{
	if(BST)
	{
		Print(BST->Left);
		cout << BST->Data << " ";
		Print(BST->Right);
	}
}

int main()
{
	BinTree BST = NULL;
	int n;
	cin >> n;
	int *num = new int[n];
	for (int i = 0; i < n; i++)
	{
		cin >> num[i];
		getchar();
		BST = Insert(BST, num[i]);
	}
	cout << "二叉搜索树的中序遍历:" << endl;
	Print(BST);
	cout << endl;
	for (int i = 0; i < n; i++)
	{
		cout << "删除" << num[i] << "?";
		getchar();
		BST = Delete(BST, num[i]);
		Print(BST);
		cout << endl;
	}
	delete[] num;
	
	system("pause");
	return 0;
}

运行结果

10
9 6 3 2 1 4 5 8 7 0
二叉搜索树的中序遍历:
0 1 2 3 4 5 6 7 8 9
删除9?
0 1 2 3 4 5 6 7 8
删除6?
0 1 2 3 4 5 7 8
删除3?
0 1 2 4 5 7 8
删除2?
0 1 4 5 7 8
删除1?
0 4 5 7 8
删除4?
0 5 7 8
删除5?
0 7 8
删除8?
0 7
删除7?
0
删除0?

请按任意键继续. . .
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值