二叉搜索树的查找/插入/删除以及二叉树搜索树的建立等基本操作实现的完整代码(可自行调试)

二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树
本文用来保存二叉搜索树的查找,插入,删除以及二叉树搜索树的建立等基本操作实现的完整代码:

直接上代码!详细算法介绍请参考此文:

二叉搜索树的查找/插入/删除以及二叉树搜索树的建立等基本操作的详细介绍

#include <iostream>
using namespace std;
const int flag = -1;
template<typename T>
struct BiTree {
    
    
	T data;
	BiTree<T>* left,//左子树 
		* right;//右子树
//构造函数 
	BiTree() {
    
     left = right = NULL; }
	BiTree(const T& theData) {
    
     data = theData; left = right = NULL; }
	BiTree(const T theData, BiTree* theLeft, BiTree* theRight)
	{
    
    
		data = theData; left = theLeft; right = theRight;
	}
};
//创建一颗二叉树搜索树
template<typename T>BiTree<T>* create_bst();
//在二叉树搜索树bst中插入一个元素data
template<typename T>BiTree<T>* insert_bst(T data, BiTree<T>* &bst);
//在二叉搜索树中查找值为data的点,并放回该结点的地址
template<typename T> BiTree<T>* find_bst(T data, BiTree<T>* bst);
//递归中序遍历二叉树
template<typename T>  void inOrder(BiTree<T>* bt);
//在二叉树搜索树中递归查找值最大的结点,并返回地址
template<typename T>BiTree<T>* find_max(BiTree<T>* bst);
//在二叉树搜索树中迭代查找值最小的结点,并返回地址
template<typename T>BiTree<T>* find_min(BiTree<T>* bst);
//在二叉搜索树bst中删除值为data的节点,并返回结果
template<typename T>BiTree<T>* delete_bst(T data, BiTree<T>*& bst);
int main()
{
    
    
	//测试数据:15 30  35 36  50 33 41 -1
	BiTree<int>* bst = create_bst<int>();
	cout << "中序遍历结果为:"; inOrder(bst);cout << endl;
	
	
	cout << "最大元素的值为:" << find_max(bst)->data << endl;
	cout << "最小元素的值为:" << find_min(bst)->data << endl;
	int x;
	cout << "输入查找的元素的值:";
	cin >> x;
	if (find_bst(x, bst)->data == x) {
    
    
		cout << "查找成功!" << endl;
	}
	else
		cout << "查找失败";
	
	cout << "输入要删除的元素的值:";
	cin >> x;
	cout << "删除该元素后,该二叉搜索树的中序遍历结果为:";
	delete_bst(x, bst);
	inOrder(bst); cout << endl;

   
}
//在二叉树搜索树bst中插入一个元素data
template<typename T>BiTree<T>* insert_bst(T data, BiTree<T>* &bst) {
    
    
	if (!bst) {
    
    //若原树为空,生成并返回一个结点的二叉搜索树
		
		bst = new BiTree<T>;
		bst->data = data;
		bst->right = bst->left = NULL;
	}
	else     //开始找要插入元素的位置
	{
    
    
		if (data < bst->data) //递归插入左子树
			bst->left = insert_bst(data, bst->left);
		
		else if (data > bst->data)//递归插入右子树
			bst->right = insert_bst(data, bst->right);
	}

	  return bst;
}
//创建一颗二叉树搜索树
template<typename T>BiTree<T>* create_bst() {
    
    
	T data;
	BiTree<T>* bst = NULL;

	cin >> data;
	while (data != flag)
	{
    
    
		
		insert_bst(data, bst);
		
		cin >> data;
	}
	return bst;
}
//递归中序遍历二叉树
template<typename T>  void inOrder(BiTree<T>* bt)
{
    
    
	if (bt == NULL)      //递归调用的结束条件 
		return;
	inOrder(bt->left);  //中序遍历递归左子树
	//visit(bt);          //访问树根
	cout << bt->data << " " ;
	inOrder(bt->right); // 中序遍历递归右子树 

}

//在二叉搜索树中查找值为data的点,并放回该结点的地址
template<typename T> BiTree<T>* find_bst(T data,BiTree<T> *bst) {
    
    
	BiTree<T>* temp = bst;
	while (temp) {
    
    
		if (temp->data == data)     //查找成功,返回结点的找到结点的地址
			return temp;
		else if (temp->data < data)//向右子树中移动,继续查找
			temp = temp->right;
		else if (temp->data > data)//向左子树中移动,继续查找
			temp = temp->left;
	}
	return NULL;  //查找失败,bst为空或者bst中没有data
}
//在二叉树搜索树中迭代查找值最小的结点,并返回地址
template<typename T>BiTree<T>* find_min(BiTree<T>* bst)
{
    
       
	 if(bst)
	while(bst->left != NULL)
		bst = bst->left;

	return bst;
}
//在二叉树搜索树中递归查找值最大的结点,并返回地址
template<typename T>BiTree<T>* find_max(BiTree<T>* bst)
{
    
    
	if (!bst)return NULL;//如果二叉树为空,直接返回NULl

    if (bst->right == NULL)//如果没有右儿子了,那么它就是最大的值
	 return bst;
    else
	return find_max(bst->right);//继续递归查找	
}
//在二叉搜索树bst中删除值为data的节点
template<typename T>BiTree<T>* delete_bst(T data, BiTree<T>* &bst) {
    
    
	BiTree<T>  * target,* pre_target,  * target_next,* pre_target_next,*temp;
	//target是要删除的目标节点,pre_target是待删结点target的双亲节点
	//target_next待删结点target的直接后继(target右子树的的最大元素)也就是我们要找的target的替代品
	//pre_target_next是结点target_next的双亲节点
	//temp临时指针
	pre_target = NULL;//这个细节用来出力要删结点就是bst的根节点的情况
	target = bst;
	/*查找到target*/
	while (target != NULL && target->data != data)
	{
    
    
		pre_target = target;         //pre_target始终指向target的双亲
		if (target->data < data)
			target = target->right;
		else if (target->data > data)
			target = target->left;
	}
	if (target == NULL)//查找失败
	{
    
    
		cout << "查找失败";
		return bst;
	}

	if (target->left && target->right)//如果目标节点的左右子树都不为空
	{
    
    
		pre_target_next = target;
		target_next = target;
		while (target_next->left != NULL)//给target_next定位
		{
    
    
			pre_target_next = target_next;   //pre_target_next始终指向target_next的双亲
			target_next = target->left;
		}
		target->data = target_next->data;

		//targetd_next已经补上去了,所以将其右子树接到其父亲节点上
		temp = target_next->right;	
		//这也要分两种情况
		if(pre_target_next == target)
			pre_target_next->right = temp;
		else
			pre_target_next->left = temp;

		delete temp;
		return bst;
	}
	else {
    
    //第二种情况,待删结点是单支结点
		  //(第一种情况即待删结点是叶节点也包含在这里)
		if (target->left != NULL)
			temp = target->left;
		else
			temp = target->right;
		if (pre_target == NULL)//如果要删除的节点就是根节点
		{
    
    
			delete temp;//直接释放掉待删结点的空间就可以了
		}
		else if(pre_target->right == target)//待删结点是其双亲节点的右孩子
		{
    
    
			pre_target->right = temp;  //则把待删结点的孩子接上去就行
		}
		else if(pre_target->left == target)
		{
    
    
			pre_target->left = temp;
		}
		delete target;
		return bst;
	}
}

程序最终测试结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45768060/article/details/106201333