概述
二叉搜索树C++实现
需要具备的基础知识
-
C++基础(继承、多态、异常机制)
-
结构体、类模板和函数模板
-
二叉搜索树(Binary Search Tree)的概念
-
左子树元素比树根小
-
右子树元素比树根大
-
左右子树都是二叉搜索树
-
-
二叉搜索树的查找、插入和删除算法
需求分析
-
查找
-
查找最大值
-
查找最小值
-
查找某个值
-
-
插入
-
删除
-
删除叶子
-
删除单子节点
-
删除双子节点
-
用左子树最大或右子树最小元素代替待删节点
-
删左子树最大或右子树最小
-
-
二叉搜索树的节点定义
二叉搜索树的节点和二叉树的节点定义一致,参见这篇文章二叉树C++实现。
二叉树的定义
二叉树类已完成定义,参见二叉树C++实现。因此定义一个二叉搜索树的模板类,公有继承自二叉树类。
//
//定义一个二叉树的模板类
//
template<class Elem>
class BSTree : public BinTree<Elem>{
protected:
public:
BSTree(){
this->m_root = nullptr;
}
};
查找需求实现
递归实现查找最大值、查找最小值的功能。
- 定义类内部受保护的成员函数rFindMax()、rFindMin()。
protected:
//
//递归查找最大值
//
TreeNode<Elem>* rFindMax(TreeNode<Elem> *root) const{
if (!root->right){
return root;
}
return rFindMax(root->right);
}
//
//递归查找最小值
//
TreeNode<Elem>* rFindMin(TreeNode<Elem> *root) const{
if (!root->left){
return root;
}
return rFindMax(root->left);
}
迭代实现查找最大值、查找最小值和查找某个值的功能。
- 定义用户API函数findMax()、findMin()、findElem(Elem val)。
//
//迭代查找最大值
//找到树根,在右边有节点,继续往右查找
//如果右边没有节点,就找到了最大值
//建议使用循环迭代。若用递归,返回值递归函数,尾递归效率比循环低
//
public:
TreeNode<Elem>* findMax() const{
if (this->m_root == nullptr){
return nullptr;
}
TreeNode<Elem> *tmpNode = this->m_root;
while (tmpNode->right){
tmpNode = tmpNode->right;
}
return tmpNode;
}
//
//迭代查找最小值
//找到树根,在左边有节点,继续往左查找
//如果左边没有节点,就找到了最大值
//
TreeNode<Elem>* findMin() const{
if (this->m_root == nullptr){
return nullptr;
}
TreeNode<Elem> *tmpNode = this->m_root;
while (tmpNode->left){
tmpNode = tmpNode->left;
}
return tmpNode;
}
//
//迭代查找目标值
//
TreeNode<Elem>* findElem(Elem val) const{
TreeNode<Elem> *tmpNode = this->m_root;
while (tmpNode && val != tmpNode->data){
if(val < tmpNode->data){
tmpNode = tmpNode->left;
}
else{
tmpNode = tmpNode->right;
}
}
return tmpNode;
}
插入需求实现
递归实现插入
- 定义类内部受保护的成员函数rinsert(注:加上virtual修饰是为了后面写平衡二叉树的子类可以重写rinsert函数)
protected:
//
//递归插入
//
virtual TreeNode<Elem>* rinsert(TreeNode<Elem> *root, Elem val){
if (!root){
root = new TreeNode<Elem>(val);
if (!root){
throw -1;
}
}
else if(val < root->data){
root->left = rinsert(root->left, val);
}
else if(val > root->data){
root->right = rinsert(root->right, val);
}
else{
throw -2;
}
return root;
}
- 定义用户API函数
//
//插入函数
//
public:
bool insert(Elem val){
try{
this->m_root = rinsert(this->m_root, val);
return true;
}
catch (int e){
return false;
}
//return true;
}
删除需求实现
递归实现删除功能,删除功能较为复杂,有如下三种场景:
-
待删节点为叶子直接delete节点
-
待删节点只有一个儿子节点的节点
-
待删节点双子节点,用左子树最大或右子树最小元素代替待删节点,再删除左子树最大或右子树最小节点
定义类内部受保护的成员函数rErase
protected:
TreeNode<Elem>* rErase(TreeNode<Elem> *root, Elem val){
TreeNode<Elem> *tmpNode;
if (!root){
throw -1;
}
else if(val < root->data){
root->left = rErase(root->left, val);
}
else if (val > root->data){
root->right = rErase(root->right, val);
}
else{
if (root->left && root->right){
tmpNode = rFindMax(root->left);
root->data = tmpNode->data;//拷贝值
root->left = rErase(root->left, tmpNode->data);//递归删除
}
else{
tmpNode = root;
root = root->left ? root->left : root->right;
delete tmpNode;
}
}
return root;
}
定义用户API函数
public:
bool erase(Elem val){
try{
this->m_root = rErase(this->m_root, val);
return true;
}
catch (int e){
return false;
}
}
代码测试
int main(){
BSTree<int> bst;
bst.insert(10);
bst.insert(5);
bst.insert(20);
bst.insert(8);
bst.insert(15);
bst.insert(2);
bst.insert(6);
bst.rPrint();//在基类中定义的函数可以在子类中使用
cout << "----------------" << endl;
bst.erase(10);
bst.rPrint();
cout << bst.findVal(15)->data << endl;
cout << "最大值:" << bst.findMax()->data << endl;
cout << "最小值:" << bst.findMin()->data << endl;
}
后续会介绍平衡二叉树,敬请期待。
完整的代码后面会上传到github供参考。
最后
以上就是单身早晨为你收集整理的二叉搜索树(Binary Search Tree)的C++实现二叉搜索树C++实现的全部内容,希望文章能够帮你解决二叉搜索树(Binary Search Tree)的C++实现二叉搜索树C++实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复