目录
- 1.什么是二叉搜索树
- 2.构建二叉搜索树
- 2.1首先搭建树的框架
- 2.2搭建搜索树的框架
- 3.二叉搜索树的插入
- 3.1非递归式插入
- 3.2递归式插入
- 4.二叉搜索树的查找
- 4.1非递归查找
- 4.2递归查找
- 5.二叉搜索树的删除
- 5.1非递归删除
- 5.2递归删除
- 6.整个代码实现
1.什么是二叉搜索树
简单来讲就是一个树的左子树的值都小于根,右子树的值都大于根。如:
这个树的特点是走一趟中序就完成了对一组树的排序。查找一个树也特别的方便,最多只需要走树的高度次。所以当这个树比较饱满时搜索的效率很高,所以被称为二叉搜索树。
2.构建二叉搜索树
2.1首先搭建树的框架
struct TreeNode
{TreeNode<V>* _left;TreeNode<V>* _right;V _val;//构造函数TreeNode(V val){_left = nullptr;_right = nullptr;_val = val;}
};
2.2搭建搜索树的框架
template<class V>
class BSTree
{typedef TreeNode<V> Node;
public:BSTree(){_head = nullptr;}private:Node* _head;};
3.二叉搜索树的插入
3.1非递归式插入
1.思路
2.代码
//插入(非递归)bool insert(V val){if (_head == nullptr){_head = new Node(val);return true;}//找到要插入结点的位置Node* parent = _head;Node* cur = _head;while (cur){if (cur->_val < val){parent = cur;cur = cur->_right;}else if (cur->_val > val){parent = cur;cur = cur->_left;}else{//相等 返回falsereturn false;}}//判断val插在parent的左还是右if (parent->_val >val){parent->_left = new Node(val);return true;}else{parent->_right = new Node(val);return true;}
3.2递归式插入
bool insertR(V val){return _insertR(_head, val);}bool _insertR(Node*& head, V val){if (head == nullptr){head = new Node(val);return true;}if (head->_val > val){_insertR(head->_left,val);}else if (head->_val < val){_insertR(head->_right, val);}else{return false;}return false;}
注意点:这个递归式插入其实也没什么难的,就是有个注意点是要引用传参。如果不是引用传参是不会修改-head的。
4.二叉搜索树的查找
4.1非递归查找
//非递归查找
bool find(V val)
{if (_head == nullptr){return false;}Node* cur = _head;while (cur){if (cur->_val < val){cur = cur->_right;}else if (cur->_val > val){cur = cur->_left;}else{return true;}}
}
4.2递归查找
bool findR(const V& val)
{return _findR(_head, val);
}bool _findR(Node* head, const V& val)
{if (head == nullptr){return false;}if (head->_val == val){return true;}return _findR(head->_left, val) || _findR(head->_right, val);
}
比较常规,没什么要解释的。
5.二叉搜索树的删除
5.1非递归删除
算法思路:
代码实现:
//非递归式删除
bool erase(const V& val)
{//第一步找到要删除的结点Node* parent = _head;Node* cur = _head;while (cur){if (cur->_val > val){parent = cur;cur = cur->_left;}else if (cur->_val < val){parent = cur;cur = cur->_right;}else{//找到了//分情况讨论if (cur->_left == nullptr){//特殊情况if (cur == _head){_head = _head->_right;return true;}if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}delete cur;return true;}else if (cur->_right == nullptr){//特殊情况if (cur == _head){_head = _head->_left;return true;}if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}delete cur;return true;}else{//找LeftMaxNode* parent = cur;Node* LeftMax = cur->_left;while (LeftMax->_right){parent = LeftMax;LeftMax = LeftMax->_right;}//交换cur与LeftMax的valswap(cur->_val, LeftMax->_val);if (parent->_left == LeftMax){parent->_left = LeftMax->_right;}else{parent->_right = LeftMax->_right;}delete LeftMax;return true;}}}return false;
}
注:这个非递归主要就是要完全考虑到删除结点会出现的可能,代码实现不复杂,但是很难一起写对,写错了调试也好很久(本人亲身经历调试了一个下午)。
5.2递归删除
算法思路:
代码实现:
bool _eraseR(Node*& head, const V& val){if (head == nullptr){return false;}else if (head->_val > val){_eraseR(head->_left, val);}else if (head->_val < val){_eraseR(head->_right, val);}else{//递归找到了Node* del = head;//三种情况//1.左子树为空if (head->_left == nullptr){head = head->_right;}//2.右子树为空else if(head->_right == nullptr){head = head->_left;}//3.左右子树都不为空else{//找LeftMaxNode* LeftMax = head->_left;while (LeftMax->_right){LeftMax = LeftMax->_right;}//交换swap(head->_val, LeftMax->_val);//递归删除return _eraseR(head->_left, val);}delete del;return true;}}
6.整个代码实现
#pragma once
template<class V>
struct TreeNode
{TreeNode<V>* _left;TreeNode<V>* _right;V _val;//构造函数TreeNode(V val){_left = nullptr;_right = nullptr;_val = val;}
};template<class V>
class BSTree
{typedef TreeNode<V> Node;
public:BSTree(){_head = nullptr;}//深拷贝BSTree(BSTree<V>& bs){_head = CopyTree(bs._head);}//赋值BSTree<V>& operator=(BSTree<V> bs){swap(_head, bs._head);return *this;}//插入(非递归)bool insert(V val){if (_head == nullptr){_head = new Node(val);return true;}//找到要插入结点的位置Node* parent = _head;Node* cur = _head;while (cur){if (cur->_val < val){parent = cur;cur = cur->_right;}else if (cur->_val > val){parent = cur;cur = cur->_left;}else{//相等 返回falsereturn false;}}//判断val插在parent的左还是右if (parent->_val >val){parent->_left = new Node(val);return true;}else{parent->_right = new Node(val);return true;}}bool insertR(V val){return _insertR(_head, val);}//非递归查找bool find(V val){if (_head == nullptr){return false;}Node* cur = _head;while (cur){if (cur->_val < val){cur = cur->_right;}else if (cur->_val > val){cur = cur->_left;}else{return true;}}}bool findR(const V& val){return _findR(_head, val);}~BSTree(){destory(_head);}void inorder(){_inorder(_head);cout << endl;}//非递归式删除bool erase(const V& val){//第一步找到要删除的结点Node* parent = _head;Node* cur = _head;while (cur){if (cur->_val > val){parent = cur;cur = cur->_left;}else if (cur->_val < val){parent = cur;cur = cur->_right;}else{//找到了//分情况讨论if (cur->_left == nullptr){//特殊情况if (cur == _head){_head = _head->_right;return true;}if (parent->_left == cur){parent->_left = cur->_right;}else{parent->_right = cur->_right;}delete cur;return true;}else if (cur->_right == nullptr){//特殊情况if (cur == _head){_head = _head->_left;return true;}if (parent->_left == cur){parent->_left = cur->_left;}else{parent->_right = cur->_left;}delete cur;return true;}else{//找LeftMaxNode* parent = cur;Node* LeftMax = cur->_left;while (LeftMax->_right){parent = LeftMax;LeftMax = LeftMax->_right;}//交换cur与LeftMax的valswap(cur->_val, LeftMax->_val);if (parent->_left == LeftMax){parent->_left = LeftMax->_right;}else{parent->_right = LeftMax->_right;}delete LeftMax;return true;}}}return false;}bool eraseR(const V& val){return _eraseR(_head, val);}private:Node* _head;void destory(Node*& head){if (head == nullptr){return;}destory(head->_left);destory(head->_right);delete head;head = nullptr;}bool _insertR(Node*& head, V val){if (head == nullptr){head = new Node(val);return true;}if (head->_val > val){_insertR(head->_left,val);}else if (head->_val < val){_insertR(head->_right, val);}else{return false;}return false;}void _inorder(Node* head){if (head == nullptr){return;}_inorder(head->_left);cout << head->_val << " ";_inorder(head->_right);}bool _findR(Node* head, const V& val){if (head == nullptr){return false;}if (head->_val == val){return true;}return _findR(head->_left, val) || _findR(head->_right, val);}bool _eraseR(Node*& head, const V& val){if (head == nullptr){return false;}else if (head->_val > val){_eraseR(head->_left, val);}else if (head->_val < val){_eraseR(head->_right, val);}else{//递归找到了Node* del = head;//三种情况//1.左子树为空if (head->_left == nullptr){head = head->_right;}//2.右子树为空else if(head->_right == nullptr){head = head->_left;}//3.左右子树都不为空else{//找LeftMaxNode* LeftMax = head->_left;while (LeftMax->_right){LeftMax = LeftMax->_right;}//交换swap(head->_val, LeftMax->_val);//递归删除return _eraseR(head->_left, val);}delete del;return true;}}Node* CopyTree(Node* head){if (head == nullptr){return nullptr;}Node* newhead = new Node(head->_val);newhead->_left = CopyTree(head->_left);newhead->_right = CopyTree(head->_right);return newhead;}};