目录
前言
二叉搜索树是一种重要的数据结构,它可以用来快速地搜索、插入和删除数据。很多算法和编程技巧都需要用到二叉搜索树,因此学习它是非常有必要的。
本篇博客将介绍C++语言中二叉搜索树的实现方式,可以帮助初学者更好地理解二叉搜索树的概念和实现过程。博客将从二叉搜索树的定义、基本操作(插入、删除和搜索)、遍历方式、实现细节等多方面进行讲解,并通过代码实现演示。
如果你想深入理解二叉搜索树,对于C++的数据结构和算法也有浓厚兴趣,请继续阅读本篇博客。
1.二叉搜索树
1.1 二叉搜索树概念
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也分别为二叉搜索树
1.2 二叉搜索树操作及实现
前提:节点定义
template<class K>
class BSTreeNode
{
public:
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
};
大体设计
template<class K, class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
bool Insert(const K& key, const V& value)
{}
Node* Find(const K& key)
{}
bool Erase(const K& key)
{}
void InOrder(Node* root)
{}
private:
Node* _root = nullptr;
};
1.2.1 二叉搜索树的查找
a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
b、最多查找高度次,走到到空,还没找到,这个值不存在。
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
{
cur = cur->_left;
}
else if (cur->_key < key)
{
cur = cur->_right;
}
else
{
return cur;
}
}
return nullptr;
}
1.2.2 二叉搜索树的插入
插入的具体过程如下:
a. 树为空,则直接新增节点,赋值给root指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点
bool Insert(const K& key)
{
if (_root == nullptr)
{
_root = new Node(key,value);
return _root;
}
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->_left = cur;
}
else
{
parent->_right=cur;
}
return true;
}
为了方便节点的创建需要在节点结构中加一个拷贝构造
BSTreeNode(const K& key)
:_left(nullptr)
, _right(nullptr)
,_key(key)
{}
1.2.3 二叉搜索树的删除
首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情 况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点
看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程如下:
情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除
情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除
情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点 中,再来处理该结点的删除问题--替换法删除
bool Erase(const K& key)
{
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
{
//1.左为空
if (cur->_left == nullptr)
{
if (parent->_left == cur)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
delete cur;
}
//右为空
else if (cur->_right == nullptr)
{
if (parent->_left == cur)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
else
{
左右都有节点
Node* pminRight = cur;
Node* minRight = cur->_right;
//找右子树最左节点
while (minRight->_left)
{
pminRight = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
if (cur->_right == minRight)
{
//如果要替换的节点是要删除的节点的右节点
pminRight->_right = minRight->_right;
}
else
{
//不确定右子树的最左节点有没有右节点
pminRight->_left = minRight->_right;
}
delete minRight;
}
return true;
}
}
return false;
}
总结
为了帮助大家更好地回顾和总结本篇博客的内容,这里给出C++二叉搜索树博客的总结:
-
二叉搜索树是一种数据结构,它是一棵二叉树,且每个节点的左子树中所有节点的值都小于该节点的值,右子树中所有节点的值都大于等于该节点的值。
-
C++中实现二叉搜索树,首先需要定义节点结构体,每个节点结构体包括数据成员和指向左、右子节点的指针。
-
实现二叉搜索树的基本操作包括插入、删除和搜索。
-
插入操作:从根节点开始,找到合适的位置插入新节点。
-
删除操作:如果要删除的节点是叶节点,则直接删除;如果要删除的节点有一个子节点,则将该节点的子节点代替该节点;如果要删除的节点有两个子节点,则找到该节点的前驱或后继节点来代替该节点。
-
搜索操作:从根节点开始,判断当前节点是否与要搜索的值相等,如果小于要搜索的值则进入右子树,如果大于则进入左子树,直到找到目标节点或搜索到空节点为止。
-
具体实现二叉搜索树时,需要考虑一些细节,如空节点、重复插入导致的数据错误、删除后的节点调整等。
通过本篇博客的学习,可以初步了解C++中二叉搜索树的实现方式和基本操作。继续深入学习后,可以掌握更多二叉搜索树的应用和变种,为编写高效的C++程序打下坚实的基础。