二叉搜索树(包含重复数据)的C++实现

由这个修改:
二叉搜索树的C++实现_qq_32523711的博客-CSDN博客

删除的时候我是递归删除的(感觉有点偷懒)

//二叉搜索树结点类型
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;
		int num;//记录数量
		switch (choice){
		case 1:
			cout << "  请输入要插入的元素:";
			cin >> val;
			tree.insert(val) ? cout << "  元素 " << val << " 插入成功!" << endl : cout << "  元素 " << val << " 已存在,插入失败!" << endl;
			cout << "--请输入操作编号:" << endl;
			break;
		case 2:
			cout << "  请输入要查询的元素:";
			cin >> val;
			num = tree.search(val);
			num ? cout << "  元素 " << val << " 有 " << num << " 个" << endl : cout << "  元素 " << val << " 不存在,查询失败!" << endl;
			cout << "--请输入操作编号:" << endl;
			break;
		case 3:
			cout << "  请输入要删除的元素:";
			cin >> val;
			num = tree.remove(val);
			num ? cout << "  删除了 " << num << " 个 " << val << " 元素" << endl : cout << "  元素 " << val << " 不存在,删除失败!" << endl;
			cout << "请输入操作编号:" << endl;
			break;
		case 4:
			tree.inorder();
			cout << "--请输入操作编号:" << endl;
			break;
		default:
			cout << "--请输入正确的操作编号!!!" << endl;
			break;
		}
	}
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搜索的删除操作可以分为以下几步: 1. 首先找到要删除的节点,可以使用二搜索的查找方法,从根节点开始递归查找。 2. 如果要删除的节点是叶子节点,直接删除即可。 3. 如果要删除的节点只有一个子节点,将该子节点接替要删除的节点即可。 4. 如果要删除的节点有两个子节点,需要找到要删除节点的中序遍历后继节点(也就是比要删除的节点大的最小节点),将其值复制到要删除的节点中,然后再将中序遍历后继节点删除。 以下是一个示例代码实现: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right class Solution: def deleteNode(self, root: TreeNode, key: int) -> TreeNode: if not root: return None # 找到要删除的节点 if key < root.val: root.left = self.deleteNode(root.left, key) elif key > root.val: root.right = self.deleteNode(root.right, key) else: # 叶子节点或只有一个子节点 if not root.left: return root.right elif not root.right: return root.left # 有两个子节点 else: successor = root.right while successor.left: successor = successor.left root.val = successor.val root.right = self.deleteNode(root.right, successor.val) return root ``` 在这个实现中,我们首先使用递归找到要删除的节点,然后根据节点的情况进行删除操作。如果节点是叶子节点或只有一个子节点,直接将其删除或将其子节点接到父节点上。如果节点有两个子节点,找到中序遍历后继节点,将其值复制到要删除的节点上,然后再将中序遍历后继节点删除。最后返回删除操作后的根节点即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值