二叉搜索树(Binary Search Tree, BST)是一种重要的数据结构,它有两种基本模型:Key模型和Key/Value模型。
一、Key模型
1.基本概念
Key模型是二叉搜索树中最简单的形式,每个节点只存储一个键值(key),没有额外的数据值(value)。这种模型主要用于判断某个键值是否存在树中。
2.Key模型的特点:
-
每个节点只包含一个键值(key)
-
节点的键值必须满足二叉搜索树的性质:左子节点的键值小于父节点,右子节点的键值大于父节点
-
不允许键值重复,即树中所有节点的键值都是唯一的
-
结构简单,适用于只需要判断元素是否存在的场景
3.典型的应用场景
-
单词拼写检查:将字典中的所有单词作为键值构建二叉搜索树,可以快速判断一个单词是否正确
-
门禁系统:存储所有授权人员的ID,快速验证某个ID是否有权限
-
数据去重:检查并确保集合中没有重复元素
单词拼写检查示例:
#include <iostream>
#include <string>
// 定义二叉搜索树节点
template<class K>
struct BSTreeNode
{
BSTreeNode<K>* _left; // 左子节点指针
BSTreeNode<K>* _right; // 右子节点指针
K _key; // 节点存储的键值
// 构造函数
BSTreeNode(const K& key)
: _left(nullptr)
, _right(nullptr)
, _key(key)
{}
};
// 定义二叉搜索树类
template<class K>
class BSTree
{
typedef BSTreeNode<K> Node; // 节点类型别名
private:
Node* _root = nullptr; // 根节点指针
public:
// 构造函数
BSTree() : _root(nullptr) {}
// 析构函数
~BSTree()
{
Destroy(_root);
}
// 插入操作
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;
}
}
Node* newNode = new Node(key);
if (parent->_key < key)
{
parent->_right = newNode;
}
else {
parent->_left = newNode;
}
return true;
}
// 查找操作
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;
}
private:
// 销毁树的辅助函数
void Destroy(Node* root)
{
if (root)
{
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
}
};
int main()
{
BSTree<std::string> dictionary;
// 初始化字典
dictionary.Insert("apple");
dictionary.Insert("banana");
dictionary.Insert("cherry");
dictionary.Insert("date");
std::cout << "===== 单词拼写检查系统 =====" << std::endl;
std::cout << "已加载基础词典(4个单词)\n";
std::cout << "输入要验证的单词(输入 exit 退出)\n\n";
std::string input;
while (true)
{
std::cout << "请输入单词: ";
std::cin >> input;
if (input == "exit")
{
std::cout << "\n=== 感谢使用 ===" << std::endl;
break;
}
if (dictionary.Find(input))
{
std::cout << "[正确] \"" << input << "\" 存在于词典中\n\n";
}
else
{
std::cout << "[警告] \"" << input
<< "\" 未在词典中找到,请注意拼写!\n\n";
}
}
return 0;
}
二、Key/Value模型
1.基本概念
Key/Value模型是二叉搜索树的重要扩展形式,每个节点存储键值对(key-value pair),支持通过key快速查找对应的value。这种模型是构建字典、索引等数据结构的核心基础。
2.核心特性
-
键值对存储:每个节点存储唯一的key及其关联的value
-
排序依据:仍然基于key维持二叉搜索树性质
-
动态更新:允许通过相同key更新value
-
高效查询:保持O(logN)平均查找时间复杂度
3.应用场景
-单词解释
-统计水果出现次数
统计水果出现次数代码示例:
#include <iostream>
#include <string>
#include <algorithm> // 用于大小写转换
// 定义二叉搜索树节点
template<class K, class V>
struct BSTreeNode
{
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
: _left(nullptr)
, _right(nullptr)
, _key(key)
, _value(value) {}
};
// 定义二叉搜索树类
template<class K, class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
Node* _root = nullptr;
// 递归销毁子树
void Destroy(Node* root)
{
if (root)
{
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
}
// 递归中序遍历打印
void _PrintInOrder(Node* root) const
{
if (root)
{
_PrintInOrder(root->_left);
std::cout << " " << root->_key << " : " << root->_value << "\n";
_PrintInOrder(root->_right);
}
}
public:
BSTree() = default;
~BSTree()
{
Destroy(_root);
}
// 插入或递增计数
void InsertOrIncrement(const K& key)
{
if (!_root)
{
_root = new Node(key, 1);
return;
}
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
{
++cur->_value;
return;
}
}
Node* newNode = new Node(key, 1);
if (parent->_key < key)
{
parent->_right = newNode;
}
else {
parent->_left = newNode;
}
}
// 打印统计结果
void PrintStatistics() const
{
std::cout << "\n===== 水果统计结果 =====\n";
_PrintInOrder(_root);
std::cout << "=======================\n";
}
};
int main()
{
BSTree<std::string, int> fruitCounter;
std::cout << "=== 水果统计系统 ===\n"
<< "输入水果名称进行统计(输入'q'结束)\n"
<< "(自动转换为小写,支持大小写混合输入)\n\n";
std::string input;
while (true)
{
std::cout << "输入水果名称: ";
std::cin >> input;
// 转换为小写
std::transform(input.begin(), input.end(), input.begin(),
\](unsigned char c) { return std::tolower(c); }); if (input == "q") break; fruitCounter.InsertOrIncrement(input); } // 输出统计结果 fruitCounter.PrintStatistics(); return 0; }

单词解释代码示例:
#include <iostream>
#include <string>
// 定义二叉搜索树节点
template<class K, class V>
struct BSTreeNode
{
BSTreeNode<K, V>* _left; // 左子节点指针
BSTreeNode<K, V>* _right; // 右子节点指针
K _key; // 键
V _value; // 值
BSTreeNode(const K& key, const V& value)
: _left(nullptr)
, _right(nullptr)
, _key(key)
, _value(value)
{}
};
// 定义二叉搜索树类
template<class K, class V>
class BSTree
{
typedef BSTreeNode<K, V> Node; // 节点类型别名
private:
Node* _root = nullptr; // 根节点指针
public:
// 构造函数
BSTree() : _root(nullptr) {}
// 析构函数
~BSTree()
{
Destroy(_root);
}
// 插入操作
bool Insert(const K& key, const V& value)
{
if (!_root) { // 空树情况
_root = new Node(key, value);
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 { // 键值已存在,更新value
cur->_value = value;
return false;
}
}
// 创建新节点并插入
Node* newNode = new Node(key, value);
if (parent->_key < key)
{
parent->_right = newNode;
}
else
{
parent->_left = newNode;
}
return true;
}
// 查找操作
V* 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 &cur->_value;
}
}
return nullptr; // 查找失败
}
private:
// 销毁树的辅助函数
void Destroy(Node* root)
{
if (root)
{
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
}
};
int main()
{
BSTree<std::string, std::string> dict;
// 构建词典
dict.Insert("apple", "A round fruit with red, green, or yellow skin and a white inside.");
dict.Insert("banana", "A long curved fruit with yellow skin and soft sweet flesh.");
// 交互查询
std::string word;
while (true)
{
std::cout << "Enter word to lookup (q to quit): ";
std::cin >> word;
if (word == "q") break;
if (auto def = dict.Find(word))
{
std::cout << "Definition: " << *def << "\n\n";
}
else
{
std::cout << "Word not found. Add definition? (y/n) ";
char choice;
std::cin >> choice;
if (choice == 'y')
{
std::string newDef;
std::cout << "Enter definition: ";
std::cin.ignore();
std::getline(std::cin, newDef);
dict.Insert(word, newDef);
std::cout << "Added!\n\n";
}
}
}
return 0;
}

码字不易,求关注
