这是我自己学习C++的第十三篇博客总结。后期我会继续把C++学习笔记开源至博客上。 上一期笔记是关于C++的多态知识,没看的同学可以过去看看: 【C++】多态-CSDN博客
https://cloud.tencent.com/developer/article/2509504
二叉搜索树,又称二叉排序树,如果其不为空,则具有以下性质:
完全二叉树:除了最后一层,其他层的节点都被完全填满,并且最后一层的节点从左到右依次排列的树形结构。
最优情况下,二叉搜索树接近完全二叉树,其高度为
。
。
二分查找也能实现
效率级别的查找,但是存在以下两个不足:
需要实现插入、删除、查找、中序遍历四个接口。 插入时:树为空,则直接新增结点,赋值给root指针;树不空,按二叉搜索树性质,插入值比当前结点大往右走,插入值比当前结点小往左走,找到空位;如果支持插入相等的值,插入值跟当前结点相等的值可以往右走,也可以往左走,找到空位置,插入新结点。 查找时:从根节点开始比较,查找x,x比根节点的值大则往右边走,x比根值小则往左边走。最多查找二叉搜索树的高度次,走到到空,如果还没找到,则这个值不存在。如果不支持插入相等的值,找到x即可返回,如果支持插入相等的值,意味着有多个x存在,一般要求查找中序的第一个x。首先查找元素是否在二叉搜索树中,如果不存在,则返回false。 如果查找元素存在则分以下四种情况分别处理:(假设要删除的结点为N)
对应以上四种情况的解决方案:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
template<class T>
struct BSTNode
{
typedef BSTNode<T> Node;
public:
BSTNode(const T& x)
:_key(x)
,_left(nullptr)
, _right(nullptr)
{}
T _key;
Node* _left;
Node* _right;
};
template<class T>
class BSTree
{
typedef BSTNode<T> Node;
typedef BSTree<T> Tree;
public:
BSTree()
:_root(nullptr)
{}
bool insert(const T& x)
{
Node* cur = _root;//从根节点开始查找
Node* parent = nullptr;
if (_root == nullptr)
{
_root = new Node(x);
return true;
}
else
{
while (cur != nullptr)
{
if (cur->_key < x)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > x)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;//不能插入已有的值
}
}
}
cur = new Node(x);
if (parent->_key < cur->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
bool erase(const T& x)
{
Node* parent = nullptr;
Node* cur = _root;//从根节点开始查找
while (cur != nullptr)
{
if (cur->_key < x)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > x)
{
parent = cur;
cur = cur->_left;
}
else
{
//找到了x,cur指向x的节点
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
}
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else
{
//cur的左右节点都不为空
//找右子树的最小节点
Node* minright = cur->_right;
Node* parent_minright = cur;
while(minright->_left!= nullptr)
{
parent_minright = minright;
minright = minright->_left;
}
cur->_key = minright->_key;
if (parent_minright->_left == minright)
{
parent_minright->_left = minright->_right;
}
else
{
parent_minright->_right = minright->_right;
}
}
return true;
}
}
return false;
}
Node* Find(const T& x)
{
Node* cur = _root;
while (cur != nullptr)
{
if (cur->_key < x)
{
cur = cur->_right;
}
else if (cur->_key > x)
{
cur = cur->_left;
}
else
{
return cur;
}
}
return nullptr;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
else
{
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
}
Node* _root;
};
int main()
{
BSTree<int> t1;
t1.insert(2);
t1.insert(1);
t1.insert(3);
t1.insert(5);
t1.insert(4);
t1.insert(0);
t1.InOrder();
cout << t1.Find(4) << endl;
t1.erase(3);
t1.InOrder();
return 0;
}
只需要在二叉树节点的构造时,设置两个值key-value即可。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
template<class T,class V>
struct BSTNode
{
typedef BSTNode<T,V> Node;
public:
BSTNode(const T& x,const V& y)
:_key(x)
,_val(y)
, _left(nullptr)
, _right(nullptr)
{}
T _key;
V _val;
Node* _left;
Node* _right;
};
template<class T, class V>
class BSTree
{
typedef BSTNode<T,V> Node;
typedef BSTree<T,V> Tree;
public:
BSTree()
:_root(nullptr)
{}
bool insert(const T& x, const V& y)
{
Node* cur = _root;
Node* parent = nullptr;
if (_root == nullptr)
{
_root = new Node(x,y);
return true;
}
else
{
while (cur != nullptr)
{
if (cur->_key < x)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > x)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
}
cur = new Node(x,y);
if (parent->_key < cur->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
bool erase(const T& x)
{
Node* parent = nullptr;
Node* cur = _root;
while (cur != nullptr)
{
if (cur->_key < x)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > x)
{
parent = cur;
cur = cur->_left;
}
else
{
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
}
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_left;
}
else
{
parent->_right = cur->_left;
}
}
}
else
{
//找右子树的最小节点
Node* minright = cur->_right;
Node* parent_minright = cur;
while (minright->_left != nullptr)
{
parent_minright = minright;
minright = minright->_left;
}
cur->_key = minright->_key;
if (parent_minright->_left == minright)
{
parent_minright->_left = minright->_right;
}
else
{
parent_minright->_right = minright->_right;
}
}
return true;
}
}
return false;
}
Node* Find(const T& x)
{
Node* cur = _root;
while (cur != nullptr)
{
if (cur->_key < x)
{
cur = cur->_right;
}
else if (cur->_key > x)
{
cur = cur->_left;
}
else
{
return cur;
}
}
return nullptr;
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
else
{
_InOrder(root->_left);
cout << root->_key<<" " << root->_val << " ";
_InOrder(root->_right);
}
}
Node* _root;
};
int main()
{
BSTree<int,int> t1;
t1.insert(2,11);
t1.insert(1,12);
t1.insert(3,13);
t1.insert(5,14);
t1.insert(4,15);
t1.insert(0,16);
t1.InOrder();
cout << t1.Find(4) << endl;
t1.erase(3);
t1.InOrder();
return 0;
}
感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有