当前位置: 首页 > web >正文

C++ 搜索二叉树(BST)详解:实现与应用

目录

一、搜索二叉树基础概念

二、BST节点结构实现

三、核心操作实现

1. 插入操作

2. 查找操作

3. 删除操作

四、BST的高级功能

1. 中序遍历

2. 拷贝构造函数和赋值运算符

3. 析构函数

五、键值对BST的实现

1. 字典应用

2. 统计应用

总结


搜索二叉树(Binary Search Tree, BST)是一种重要的数据结构,它结合了链表的灵活性和数组的快速查找优势。本文将详细介绍C++中搜索二叉树的实现原理、核心操作以及实际应用场景。

一、搜索二叉树基础概念

搜索二叉树是一种特殊的二叉树,它具有以下性质:

  • 每个节点包含一个键值(key)
  • 左子树所有节点的键值小于根节点的键值
  • 右子树所有节点的键值大于根节点的键值
  • 左右子树也分别是搜索二叉树

这种结构使得查找、插入和删除操作的平均时间复杂度为O(log n)。

二、BST节点结构实现

我们首先定义BST的节点结构:

template<class K>
class BSTreeNode {
public:K _key;                 // 节点存储的键值BSTreeNode<K>* _left;    // 左子节点指针BSTreeNode<K>* _right;   // 右子节点指针BSTreeNode(const K& key):_key(key),_left(nullptr),_right(nullptr){}
};

三、核心操作实现

1. 插入操作

非递归实现:

bool Insert(const K& key) {if (_root == nullptr) {_root = new Node(key);return true;}Node* parent = nullptr;Node* cur = _root;while (cur) {if (cur->_key < key) {parent = cur;cur = cur->_right;}else if (cur->_key > key) {parent = cur;cur = cur->_left;}else {return false; // 键值已存在}}cur = new Node(key);if (parent->_key < key) {parent->_right = cur;}else {parent->_left = cur;}return true;
}

递归实现:

bool _InsertR(Node*& root, const K& key) {if (root == nullptr) {root = new Node(key);return true;}if (root->_key < key) {return _InsertR(root->_right, key);}else if (root->_key > key) {return _InsertR(root->_left, key);}else {return false; // 键值已存在}
}

2. 查找操作

非递归实现:

bool Find(const K& key) {Node* cur = _root;while (cur) {if (cur->_key < key) {cur = cur->_right;}else if (cur->_key > key) {cur = cur->_left;}else {return true;}}return false;
}

递归实现:

bool _FindR(Node* root, const K& key) {if (root == nullptr) {return false;}if (root->_key < key) {return _FindR(root->_right, key);}else if (root->_key > key) {return _FindR(root->_left, key);}else {return true;}
}

3. 删除操作

删除操作较为复杂,需要考虑三种情况:

  1. 删除叶子节点
  2. 删除只有左子树或右子树的节点
  3. 删除有两个子树的节点

非递归实现:

bool Erase(const K& key) {Node* cur = _root;Node* parent = cur;while (cur) {if (cur->_key < key) {parent = cur;cur = cur->_right;}else if (cur->_key > key) {parent = cur;cur = cur->_left;}else {// 找到要删除的节点if (cur->_left == nullptr) {// 左子树为空的情况if (cur == _root) {_root = cur->_right;}else {if (parent->_right == cur) {parent->_right = cur->_right;}else {parent->_left = cur->_right;}}}else if (cur->_right == nullptr) {// 右子树为空的情况if (cur == _root) {_root = cur->_left;}else {if (parent->_left == cur) {parent->_left = cur->_left;}else {parent->_right = cur->_left;}}}else {// 左右子树都不为空的情况Node* parent = cur;Node* leftMax = cur->_left;while (leftMax->_right) {parent = leftMax;leftMax = leftMax->_right;}swap(cur->_key, leftMax->_key);if (parent->_left == leftMax) {parent->_left = leftMax->_left;}else {parent->_right = leftMax->_left;}cur = leftMax;}delete cur;return true;}}return false;
}

递归实现:

bool _EraseR(Node*& root, const K& key) {if (root == nullptr) {return false;}if (root->_key < key) {return _EraseR(root->_right, key);}else if (root->_key > key) {return _EraseR(root->_left, key);}else {Node* del = root;if (root->_left == nullptr) {root = root->_right;}else if (root->_right == nullptr) {root = root->_left;}else {Node* leftMax = root->_left;while (leftMax->_right) {leftMax = leftMax->_right;}swap(root->_key, leftMax->_key);return _EraseR(root->_left, key);}delete del;return true;}
}

四、BST的高级功能

1. 中序遍历

中序遍历BST会得到一个有序的序列:

void _InOrder(Node* root) {if (root == nullptr) {return;}_InOrder(root->_left);cout << root->_key << " ";_InOrder(root->_right);
}

2. 拷贝构造函数和赋值运算符

BSTree(const BSTree<K>& t) {_root = Copy(t._root);
}BSTree<K>& operator=(BSTree<K> t) {swap(_root, t._root);return *this;
}Node* Copy(Node* root) {if (root == nullptr) return nullptr;Node* copyroot = new Node(root->_key);copyroot->_left = Copy(root->_left);copyroot->_right = Copy(root->_right);return copyroot;
}

3. 析构函数

~BSTree() {Destroy(_root);
}void Destroy(Node*& root) {if (root == nullptr) return;Destroy(root->_left);Destroy(root->_right);delete root;root = nullptr;
}

五、键值对BST的实现

我们可以扩展BST以支持键值对存储:

template<class K, class V>
class BSTreeNode {
public:K _key;V _value;BSTreeNode<K,V>* _left;BSTreeNode<K,V>* _right;BSTreeNode(const K& key, const V& value):_key(key),_value(value),_left(nullptr),_right(nullptr){}
};

这种结构非常适合实现字典或统计应用:

1. 字典应用

void TestBSTree1() {BSTree<string, string> dict;dict.InsertR("insert", "插入");dict.InsertR("sort", "排序");dict.InsertR("right", "右边");dict.InsertR("date", "日期");string str;while (cin >> str) {auto ret = dict.FindR(str);if (ret) {cout << ret->_value << endl;}else {cout << "无此单词" << endl;}}
}

2. 统计应用

void TestBSTree2() {string arr[] = { "苹果","西瓜","西瓜","西瓜","香蕉","苹果", "苹果", "苹果", "苹果", "苹果" };BSTree<string, int> countTree;for (auto& str : arr) {auto ret = countTree.FindR(str);if (ret == nullptr) {countTree.InsertR(str, 1);}else {ret->_value++;}}countTree.InOrder();
}

总结

搜索二叉树是数据结构与算法中的重要内容,掌握它的实现原理和应用场景对于提升编程能力非常有帮助。本文详细介绍了C++中BST的实现方法,包括基本操作和高级功能,并展示了它在实际中的应用。理解这些内容将为学习更复杂的数据结构打下坚实基础。

希望这篇博客对你理解和使用搜索二叉树有所帮助!如果有任何问题,欢迎在评论区留言讨论。

http://www.xdnf.cn/news/12886.html

相关文章:

  • 从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(十二)
  • DeepSeek10-RAG相关模型知识说明
  • Vue入门到实战之第一篇【超基础】
  • SeaweedFS S3 Spring Boot Starter
  • 三十五、面向对象底层逻辑-Spring MVC中AbstractXlsxStreamingView的设计
  • 网络编程(TCP编程)
  • NVIC (嵌套向量中断控制器)是什么?
  • AI智能驱动浏览器工具Browser Use详解
  • 【动画】Unity2D骨骼动画-Animation2D
  • 知名的WordPress模板团队
  • 【西门子杯工业嵌入式-5-串口实现数据收发】
  • 算法打卡17天(补)
  • 03.数据类型
  • vue项目使用svg图标
  • 软件工程的软件生命周期通常分为以下主要阶段
  • 计算机网络基础总结:TCP/IP 模型、TCP vs UDP、DNS 查询过程
  • React、Git、计网、发展趋势等内容——前端面试宝典(字节、小红书和美团)
  • Vue项目PDF目录功能集成【一】——方案深度思考
  • Android 线性布局中常见的冲突属性总结
  • 在网络排错中,经常会用到的操作命令和其作用
  • 剑指offer19_链表中倒数第k个节点
  • Jmeter(四) - 如何在jmeter中创建网络测试计划
  • protues仿真+C51+外部中断
  • MATLAB生成大规模无线通信网络拓扑(任意节点数量)
  • 微服务体系下将环境流量路由到开发本机
  • spring中的@KafkaListener 注解详解
  • NLP学习路线图(三十四): 命名实体识别(NER)
  • unity实现自定义粒子系统
  • java 时区时间转为UTC
  • 云原生架构赋能企业数字化转型:从理念到落地的系统性探索