目录
一 二叉搜索树 (KEY)
1 二叉搜索树
1.1 概念
1.2 基本结构
2 二叉搜索树的查找
2.1 思路
2.2 代码实现
3 二叉搜索树的插入
3.1 思路
3.2 代码实现
4 二叉搜索树的删除
4.1 分情况处理
4.2 代码实现
二 二叉搜索树(KEY_VALUE)
1 KV模型基本概念
2 代码实现
2.1 基本结构
2.2 数据插入
2.3 查找
2.4删除
三 二叉搜索树的性能
四 完整代码
1 BinarySearchTree.h
2 BinarySearchTree.cpp
#pragma once
#include
using namespace std;
//二叉搜索树的KEY模型
namespace KEY
{
//树节点
template
struct BSTreeNode
{
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
BSTreeNode(const K& key)
: _left(nullptr)
, _right(nullptr)
, _key(key)
{}
};
//二叉搜索树
template
class BSTree
{
typedef BSTreeNode Node;
public:
//BSTree() = default;
//构造函数
BSTree()
:_root(nullptr)
{}
private:
Node* _root = nullptr;
};
}
① 若根节点为空:返回flase,若不为空:
②如果根节点key==查找key,返回true
③如果根节点key >查找key,在其左子树查找。如果根节点key <查找key,在其右子树查找。否则返回false
//搜索存储在树中的数据
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
//要搜索的值比较大,就向右边找
if (cur->_key < key)
{
cur = cur->_right;
}
//要搜索的值比较小,就向左边找
else if (cur->_key > key)
{
cur = cur->_left;
}
//找到了,返回位置
else
{
return cur;
}
}
//没找到返回空
return nullptr;
}
//插入数据
bool Insert(const K& key)
{
//如果树为空,开一个节点,直接将数据插入
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
//不为空
//查找要插入的位置
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 < cur->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
//删除树中的数据
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
{
//情况一:需要删除的结点左子树为空
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
delete cur;
}
//情况二:需要删除的结点右子树为空
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;
}
}
delete cur;
}
情况三:需要删除的结点左右子树都不为空
else
{
// 找到右树最小节点去替代删除
Node* minRightParent = cur;
Node* minRight = cur->_right;
while (minRight->_left)
{
minRightParent = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
if (minRight == minRightParent->_left)
minRightParent->_left = minRight->_right;
else
minRightParent->_right = minRight->_right;
delete minRight;
}
return true;
}
}
return false;
}
每一个关键码key,都有与之对应的值Value,即
namespace KEY_VALUE
{
//树结点
template
struct BSTreeNode
{
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
: _left(nullptr)
, _right(nullptr)
, _key(key)
, _value(value)
{}
};
//树
template
class BSTree
{
typedef BSTreeNode Node;
public:
private:
Node* _root = nullptr;
};
}
//插入
pair Insert(const K& key, const V& value)
{
if (_root == nullptr)
{
_root = new Node(key, value);
return make_pair(_root, true);
}
// 查找要插入的位置
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 make_pair(cur, false);
}
}
cur = new Node(key, value);
if (parent->_key < cur->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return make_pair(cur, true);
}
//查找
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return cur;
}
}
return nullptr;
}
//删除
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
{
// 删除
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
delete cur;
}
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;
}
}
delete cur;
}
else
{
// 找到右树最小节点去替代删除
Node* minRightParent = cur;
Node* minRight = cur->_right;
while (minRight->_left)
{
minRightParent = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
if (minRight == minRightParent->_left)
minRightParent->_left = minRight->_right;
else
minRightParent->_right = minRight->_right;
delete minRight;
}
return true;
}
}
return false;
}
#pragma once
#include
using namespace std;
//二叉搜索树的KEY模型
namespace KEY
{
//树节点
template
struct BSTreeNode
{
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
BSTreeNode(const K& key)
: _left(nullptr)
, _right(nullptr)
, _key(key)
{}
};
//二叉搜索树
template
class BSTree
{
typedef BSTreeNode Node;
public:
//BSTree() = default;
//构造函数
BSTree()
:_root(nullptr)
{}
//BSTree(const BSTree& t)
//拷贝构造函数
BSTree(const BSTree& t)
{
_root = _Copy(t._root);
}
// t1 = t2
//赋值运算符重载
BSTree& operator=(BSTree t)
{
std::swap(_root, t._root);
return *this;
}
//析构函数
~BSTree()
{
_Destroy(_root);
}
//插入数据
bool Insert(const K& key)
{
//如果树为空,开一个节点,直接将数据插入
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
//不为空
//查找要插入的位置
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 < cur->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
//搜索存储在树中的数据
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
//要搜索的值比较大,就向右边找
if (cur->_key < key)
{
cur = cur->_right;
}
//要搜索的值比较小,就向左边找
else if (cur->_key > key)
{
cur = cur->_left;
}
//找到了,返回位置
else
{
return cur;
}
}
//没找到返回空
return nullptr;
}
//删除树中的数据
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
{
//情况一:需要删除的结点左子树为空
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
delete cur;
}
//情况二:需要删除的结点右子树为空
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;
}
}
delete cur;
}
情况三:需要删除的结点左右子树都不为空
else
{
// 找到右树最小节点去替代删除
Node* minRightParent = cur;
Node* minRight = cur->_right;
while (minRight->_left)
{
minRightParent = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
if (minRight == minRightParent->_left)
minRightParent->_left = minRight->_right;
else
minRightParent->_right = minRight->_right;
delete minRight;
}
return true;
}
}
return false;
}
//中序遍历二叉搜索树(升序)
void InOrder()
{
_InOrder(_root);
cout << endl;
}
//递归版本
bool InsertR(const K& key)
{
return _InsertR(_root, key);
}
Node* FindR(const K& key)
{
return _FindR(_root, key);
}
bool EraseR(const K& key)
{
return _EraseR(_root, key);
}
private:
void _Destroy(Node* root)
{
if (root == nullptr)
{
return;
}
_Destroy(root->_left);
_Destroy(root->_right);
delete root;
}
Node* _Copy(Node* root)
{
if (root == nullptr)
{
return nullptr;
}
Node* newRoot = new Node(root->_key);
newRoot->_left = _Copy(root->_left);
newRoot->_right = _Copy(root->_right);
return newRoot;
}
bool _EraseR(Node*& root, const K& key)
{
if (root == nullptr)
return false;
if (root->_key < key)
{
return _EraseR(root->_right, key);
}
else if (root->_key > key)
{
return _EraseR(root->_left, key);
}
else
{
// 删除
Node* del = root;
if (root->_left == nullptr)
{
root = root->_right;
}
else if (root->_right == nullptr)
{
root = root->_left;
}
else
{
// 替代法删除
Node* minRight = root->_right;
while (minRight->_left)
{
minRight = minRight->_left;
}
root->_key = minRight->_key;
// 转换成递归在右子树种删除最小节点
return _EraseR(root->_right, minRight->_key);
}
delete del;
return true;
}
}
Node* _FindR(Node* root, const K& key)
{
if (root == nullptr)
return nullptr;
if (root->_key < key)
return _FindR(root->_right, key);
else if (root->_key > key)
return _FindR(root->_left, key);
else
return root;
}
bool _InsertR(Node*& root, const K& key)
{
if (root == nullptr)
{
root = new Node(key);
return true;
}
else
{
if (root->_key < key)
{
return _InsertR(root->_right, key);
}
else if (root->_key > key)
{
return _InsertR(root->_left, key);
}
else
{
return false;
}
}
}
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root = nullptr;
};
}
//二叉搜索树的KEY_VALUE模型
namespace KEY_VALUE
{
//树结点
template
struct BSTreeNode
{
BSTreeNode* _left;
BSTreeNode* _right;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
: _left(nullptr)
, _right(nullptr)
, _key(key)
, _value(value)
{}
};
//树
template
class BSTree
{
typedef BSTreeNode Node;
public:
V& operator[](const K& key)
{
pair ret = Insert(key, V());
return ret.first->_value;
}
//插入
pair Insert(const K& key, const V& value)
{
if (_root == nullptr)
{
_root = new Node(key, value);
return make_pair(_root, true);
}
// 查找要插入的位置
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 make_pair(cur, false);
}
}
cur = new Node(key, value);
if (parent->_key < cur->_key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return make_pair(cur, true);
}
//查找
Node* Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
else
{
return cur;
}
}
return nullptr;
}
//删除
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
{
// 删除
if (cur->_left == nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (cur == parent->_left)
{
parent->_left = cur->_right;
}
else
{
parent->_right = cur->_right;
}
}
delete cur;
}
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;
}
}
delete cur;
}
else
{
// 找到右树最小节点去替代删除
Node* minRightParent = cur;
Node* minRight = cur->_right;
while (minRight->_left)
{
minRightParent = minRight;
minRight = minRight->_left;
}
cur->_key = minRight->_key;
if (minRight == minRightParent->_left)
minRightParent->_left = minRight->_right;
else
minRightParent->_right = minRight->_right;
delete minRight;
}
return true;
}
}
return false;
}
//中序遍历
void InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << ":" << root->_value << endl;
_InOrder(root->_right);
}
private:
Node* _root = nullptr;
};
}
#include "BinarySearchTree.h"
void TestBSTree1()
{
int a[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
KEY::BSTree t;
for (auto e : a)
{
//t.Insert(e);
t.InsertR(e);
}
t.InOrder();
KEY::BSTree copy = t;
copy.InOrder();
t.Erase(7);
t.InOrder();
t.Erase(5);
t.InOrder();
for (auto e : a)
{
//t.Erase(e);
t.EraseR(e);
t.InOrder();
}
}
void TestBSTree2()
{
KEY_VALUE::BSTree dict;
dict.Insert("sort", "排序");
dict.Insert("insert", "插入");
dict.Insert("tree", "树");
dict.Insert("right", "右边");
// ...
string str;
while (cin >> str)
{
if (str == "Q")
{
break;
}
else
{
auto ret = dict.Find(str);
if (ret == nullptr)
{
cout << "拼写错误,没找到" << endl;
}
else
{
cout << ret->_key << "->" << ret->_value << endl;
}
}
}
}
void TestBSTree3()
{
// 统计字符串出现次数
string str[] = { "sort", "sort","insert", "tree", "sort", "insert","sort", "insert", "sort", "tree", "sort", "test", "sort" };
KEY_VALUE::BSTree countTree;
for (auto& e : str)
{
countTree[e]++;
}
countTree.InOrder();
}
int main()
{
//TestBSTree1();
//TestBSTree2();
TestBSTree3();
return 0;
}