【C++】实现一个搜索二叉树(BSTree):从定义到操作全解析

本文详细介绍了如何使用模板类BSTreeNode和BSTree实现搜索二叉树,包括节点定义、插入、查找、删除操作以及中序遍历,还提供了递归版本的代码示例。通过实例展示了如何构建和操作二叉搜索树,提升数据结构和算法理解。


搜索二叉树(Binary Search Tree,简称BST)是一种特殊的二叉树,它满足任一节点的左子树中的所有节点的值都小于该节点的值,右子树中的所有节点的值都大于该节点的值。这使得BST在查找、插入和删除操作上具有较高的效率。本文将详细介绍如何从零开始实现一个搜索二叉树,包括其节点结构的定义和一系列基本操作的实现。

BSTreeNode类的定义

首先,我们需要定义树的节点BSTreeNode,它将作为树的基础结构:

template<class K, class V>
class BSTreeNode {
   
   
public:
    K _key;     // 节点存储的键
    V _value;   // 节点存储的值
    BSTreeNode* _left;   // 左子节点
    BSTreeNode* _right;  // 右子节点

    BSTreeNode(const K& key, const V& value)
        : _key(key), _value(value), _left(nullptr), _right(nullptr) {
   
   }
};

BSTree类的实现

接着,我们来实现BSTree类,它包含了一系列操作二叉搜索树的方法:

插入操作

插入操作Insert的核心思想是比较待插入节点的键与当前节点的键,决定向左子树还是右子树递归地进行插入操作。

	bool Insert(const K& key, const V& value) {
   
   
		if (!_root) {
   
   
			_root = new Node(key, value);
			return true;
		}

		Node* parent = nullptr;
		Node* current = _root;
		while (current) {
   
   
			parent = current;
			if (key < current->_key) {
   
   
				current = current->_left;
			}
			else if (key > current->_key) {
   
   
				current = current->_right;
			}
			else {
   
   
				return false; // key已经存在
			}
		}

		if (key < parent->_key) {
   
   
			parent->_left = new Node(key, value);
		}
		else {
   
   
			parent->_right = new Node(key, value);
		}

		return true;
	}

查找操作

查找操作Find通过逐层比较键值,沿树向下移动,直到找到匹配的节点或达到叶子节点。

Node* Find(const K& key) {
   
   
	Node* current = _root;
	while (current) {
   
   
		if (key < current->_key) {
   
   
			current = current->_left;
		}
		else if (key > current->_key) {
   
   
			current = current->_right;
		}
		else {
   
   
			return current; // 找到了
		}
	}
	return nullptr; // 没有找到
}

删除操作

删除操作Erase是最复杂的,它需要处理三种情况:被删除节点是叶子节点、只有一个子节点、有两个子节点。

  1. 被删除节点是叶子节点:直接删除该节点,并将其父节点的相应指针设置为nullptr
  2. 被删除节点只有一个子节点:删除该节点,并将其父节点的相应指针指向其子节点。
  3. 被删除节点有两个子节点:找到该节点的中序后继节点(右子树中的最小节点),用它来替换被删除节点的键和值,然后删除中序后继节点。

下面是Erase函数的实现代码:

bool Erase(const K& key) {
   
   
	Node* parent = nullptr;
	Node* current = _root;
	// 查找key对应的节点,同时记录其父节点
	while (current != nullptr && current->_key != key) {
   
   
		parent = current;
		if (key < current->_key) {
   
   
			current = current->_left;
		}
		else {
   
   
			current = current->_right;
		}

		if (current == nullptr) {
   
   
			// 没有找到对应的节点
			return false;
		}
	}
	//case1&2: 没有孩子或者只有一个孩子
	if (current->_left == nullptr || current->_right == nullptr) {
   
   
		Node* child = (current->_left == nullptr) ? current->_right : current->_left;
		if (parent == nullptr) {
   
   
			// 删除的是根节点
			_root = child;
		}
		else {
   
   
			if (parent->_left == current) {
   
   
				parent->_left = child;
			}
			else {
   
   
				parent->_right = child;
			}
		}
		delete current;
	}
	else {
   
   
		// case 3: 两个孩子
		// 找到右子树最小节点, 即中序后继节点
		Node* successor = current->_right;
		Node* successorParent = current;
		while (successor->_left != nullptr) {
   
   
			successorParent = successor;
			successor = successor->_left;
		}

		// 替换current 的节点和键值
		current->_key = successor->_key;
		current->_value = successor->_value;
		if 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Q_hd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值