文章目录
BST(Binary Search Tree):二叉查找树,也叫二叉搜索树,或称二叉排序树Binary Sort Tree
1.BST的性质:
- 每一个元素都有一个键值,并且键值不允许重复
- 左子树的所有节点的键值都小于根结点
- 右子树的所有节点的键值都大于根结点
- 左右子树都是一个BST树
2.BST的遍历
BST是一种特殊的二叉树,它的遍历方法和二叉树相同,分为前序遍历、中序遍历和后序遍历,这3种遍历的实现(递归和迭代)我在前面的文章已经介绍过了,有兴趣可以参考一下。
二叉树的迭代法前序遍历的两种方法
二叉树的迭代法后序、中序遍历
二叉树的非递归(迭代)统一实现“前中后序遍历”详解
二叉树的层序遍历
3.BST的基本运算、方法
定义好3个结构、类:
- struct Element{}:BST的节点的元素结构
- class BstNode:BST的节点类
- class Bst:BST类
/******************二叉查找树节点键值结构************************/
template <typename Type>
struct Element
{
friend class BstNode<Type>;
friend class Bst<Type>;
public:
Element(){
}
Element(Type _key):key(_key){
}
//private:
Type key;//键值
//可以添加更多数据
};
/******************二叉查找树节点类************************/
template <typename Type>
class BstNode
{
friend class Bst<Type>;
public:
BstNode():leftChild(nullptr), rightChild(nullptr){
};
BstNode(Element<Type> _content) :leftChild(nullptr), rightChild(nullptr)
{
content.key = _content.key;
};
//private:
Element<Type> content;
BstNode<Type> *leftChild;
BstNode<Type> *rightChild;
};
/******************二叉查找树类************************/
template <typename Type>
class Bst
{
public:
Bst(BstNode<Type> *_root = nullptr) :root(_root){
}
void Insert(const Element<Type>& _data);//插入
BstNode<Type>* Search(const Element<Type>& _data);//递归查找
BstNode<Type>* Search(BstNode<Type>* node, const Element<Type>& _data);
BstNode<Type>* IterSearch(const Element<Type>& _data);//迭代查找
BstNode<Type>* FindMax();//查找子树的最大节点
BstNode<Type>* FindMax(BstNode<Type>* node);
BstNode<Type>* FindMin();//查找子树的最小节点
BstNode<Type>* FindMin(BstNode<Type>* node);
void Delete(const Element<Type>& _data);//删除
void InOrder();//中序遍历
void InOrder(BstNode<Type>* node);
void LevelOrder();//层序遍历
void LevelOrder(BstNode<Type>* node);
private:
BstNode<Type>* FindParent(BstNode<Type>* node);
BstNode<Type> *root;
};
3.1插入
- 若BST为空,则插入结点做为根节点;
- 若BST不空,插入规则为:比节点键值小,插入在节点的左子树;比节点键值大,插入在节点的右子树
代码中均有详细注释,如下:
template <typename Type>
void Bst<Type>::Insert(const Element<Type>& _data)
{
BstNode<Type> *newNode = new BstNode<Type>(_data);
BstNode<Type> *cur = root;
BstNode<Type> *tmp = root;
//若bst树为空,则插入的节点就是根节点
if (cur == nullptr)
root = newNode;
//若bst树不空
else{
//1.找到连接newNode的父节点
while (cur){
tmp = cur;//tmp就是保存newNode的父节点
if (newNode->content.key < cur->content.key){
cur = cur->leftChild;
}
else if(newNode->content.key > cur->content.key){
cur = cur->rightChild;
}
else{
throw "Error";
}
}
//2.确定newNode作为左节点还是右节点
if (newNode->content.key < tmp->content.key){
tmp->leftChild = newNode;
}
else if (newNode->content.key > tmp->content.key){
tmp->rightChild = newNode;
}
else{
; }
}
}
3.2查找
我在这里给出递归和迭代两种方法:
3.2.1查找之迭代法
代码如下:
template <typename Type>
BstNode<Type>* Bst<Type>::IterSearch(const Element<Type>& _data)
{
BstNode<Type> *cur = root;
while (cur){
if (cur->content.key == _data.key)
return cur;
else if (_data.key < cur->content.key)
cur = cur->leftChild;
else if (_data.key > cur->content.key)
cur = cur->rightChild;
else{
}
}
return nullptr;
}
3.2.2查找之递归法
递归法需要用到重载。一个参数的Search函数是给类外部调用;由于使用递归调用,所以重载Search函数,增加一个表示节点类的参数。两个参数的Search函数应该作为类内部的私有成员函数。
BstNode<Type>* Search(const Element<Type>& _data);//递归查找
BstNode<Type>* Search(BstNode<Type>* node, const Element<Type>& _data);
代码如下:
template <typename Type>
Bst