二叉搜索树的C++实现

主要包含删除、插入和搜索三个操作,关于操作的解释,可以看这里:

二叉树基础(下)

直接贴代码,参考:【二叉搜索树】的详细实现(C++)

重点需要注意的是,插入和删除操作传入的节点参数一定得是节点指针的引用,单单传入节点的指针是错误的,其实原因就是值传递和引用传递中形参初始化的区别,这两个操作设计到原节点的修改。

而遍历和查找操作则不强制要求必须传入节点指针的引用,直接传入节点的指针也是可以的,因为这两个操作并不会修改数据。

其他的都在注释里了。

//二叉搜索树结点类型
template<class T> struct BSTNode
{
	T data; //数据域
	BSTNode<T> *left, *right;
	BSTNode() :left(NULL), right(NULL){}
	BSTNode(const T d, BSTNode<T>* L = NULL, BSTNode<T>* R = NULL) : data(d), left(L), right(R){}
};
//二叉搜索树
template<class T> class BST{
public:
	BST() : root(NULL){
		T x;
		// 新的一行ctrl+z结束读取
		cout << "请输入待创建二叉树的节点值(回车后ctrl+z结束输入):" << endl;
		while (cin >> x)	
			Insert(x, root);
	}
	// 析构
	~BST(){ Destroy(root); }
	// 插入
	bool insert(T x){
		return Insert(x, root);
	}
	// 删除
	bool remove(T x){
		return Remove(x, root);
	}
	// 搜索
	bool search(T x){
		return (Search(x, root) != NULL) ? true : false;
	}
	// 中序遍历
	void inorder(){
		cout << "中序遍历:";
		Inorder(root);
		cout << endl;
	}
protected:
	// 析构函数
	void Destroy(BSTNode<T>* &root){
		if (root == NULL)
			return;
		if (root->left != NULL)
			Destroy(root->left);
		if (root->right != NULL)
			Destroy(root->right);
		delete root;root = nullptr;
	}
	// ptr为根的二叉搜索树中插入值为a的结点
	bool Insert(const T& a, BSTNode<T>* &ptr){ //第二个参数是指针的引用,因为插入是要进行修改的
		if (ptr == NULL){
			ptr = new BSTNode<T>(a);
			return true;
		}
		else if(a < ptr->data)//小于,插入左子树
			Insert(a, ptr->left);
		else if(a > ptr->data)// 大于,插入右子树
			Insert(a, ptr->right);
		else //已在树中,不插入
			return false;
	}
	// ptr为根的二叉搜索树中删除值为a的结点
	bool Remove(const T& a, BSTNode<T>* &ptr){
		if (ptr == NULL) return false;
		BSTNode<T>* tmp;
		if (a < ptr->data)
			Remove(a, ptr->left);
		else if (a > ptr->data)
			Remove(a, ptr->right);
		// 找到了要删除的结点
		// 1、要删除的结点有左右子树
		else if (ptr->left != NULL && ptr->right != NULL){
			tmp = ptr->right; //右子树中搜索最小值(中序遍历的第一个结点)
			while (tmp->left != NULL)
				tmp = tmp->left;
			ptr->data = tmp->data; //替换结点值(待删除结点与待删除结点的右子树中的最小值结点)
			Remove(ptr->data, ptr->right); //删除掉这个最小值结点
		}
		// 2、不同时有左右子树
		// 3、为叶子结点
		else{
			tmp = ptr;
			if (ptr->left == NULL) //只有右子树
				ptr = ptr->right; //将右子树接过来
			else //只有左子树
				ptr = ptr->left; //将左子树接过来
			delete tmp;tmp = nullptr;
			return true;
		}
	}
	// ptr为根的二叉树中搜索值为x的结点
	BSTNode<T>* Search(T x, BSTNode<T>* ptr){//搜索不涉及修改,参数有没有引用都可以
		if (ptr == NULL)	
			return NULL;
		else if (x < ptr->data)
			return Search(x, ptr->left);
		else if (x > ptr->data)
			return Search(x, ptr->right);
		else
			return ptr;
	}
	//中序遍历
	void Inorder(BSTNode<T>* root){//遍历不涉及修改,参数有没有引用都可以
		if (root != NULL){
			Inorder(root->left);
			cout << root->data << " ";
			Inorder(root->right);
		}
	}
private:
	BSTNode<T>* root;
};

测试的cpp

#include <iostream>
#include "bsearchTree.h"

using namespace std;

int main(){
	BST<int> tree;
	cout << "请输入编号选择要进行的操作:" << endl;
	cout << "1:插入元素  2:查询元素  3:删除元素  4:遍历" << endl;
	
	cin.clear(); //清除错误状态(上一轮输入了ctrl+z)

	int choice;
	cout << "--请输入操作编号:" << endl;
	while (cin >> choice){
		int val;
		switch (choice){
			case 1:
				cout << "  请输入要插入的元素:";
				cin >> val;
				tree.insert(val) ? cout << "  元素 " << val << " 插入成功!" << endl : cout << "  元素 " << val << " 已存在,插入失败!" << endl;
				cout << "--请输入操作编号:" << endl;
				break;
			case 2:
				cout << "  请输入要查询的元素:";
				cin >> val;
				tree.search(val) ? cout << "  元素 " << val << " 查询成功!" << endl : cout << "  元素 " << val << " 不存在,查询失败!" << endl;
				cout << "--请输入操作编号:" << endl;
				break;
			case 3:
				cout << "  请输入要删除的元素:";
				cin >> val;
				tree.remove(val) ? cout << "  元素 " << val << " 删除成功!" << endl : cout << "  元素 " << val << " 不存在,删除失败!" << endl;
				cout << "请输入操作编号:" << endl;
				break;
			case 4:
				tree.inorder();
				cout << "--请输入操作编号:" << endl;
				break;
			default:
				cout << "--请输入正确的操作编号!!!" << endl;
				break;
		}
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值