二叉搜索树是经典的数据结构,对于随机无序的大规模数据查询,可以做到O(logN)的插入及查询,实现没有想象的那么容易,当然也没有太复杂。
以下是基于递归实现。
#ifndef BSTREE
#define BSTREE
#include <cassert>
#include <vector>
namespace ST
{
template <typename K, typename V>
struct BST; //声明二叉树
template <typename K, typename V>
struct BNode //链表节点
{
BNode(const K &keys, const V &vals, int Num)
: key(keys), val(vals), N(Num) {}
private:
K key;
V val;
BNode *left = nullptr;
BNode *right = nullptr;
int N = 0;
friend BST<K, V>; //设置二叉树为友元
};
template <typename K, typename V>
struct BST //定义二叉树
{
BST() = default; //默认构造
BST(const BST &rhs) //拷贝构造
: root(new BNode<K, V>(rhs.root->key, rhs.root->val, rhs.root->N))
{
copy(rhs.root, root);
}
BST &operator=(const BST &rhs) //拷贝赋值
{
if (root == rhs.root)
{
return *this;
}
if (root)
{
debuild(root);
root = nullptr;
}
if (rhs.root)
{
root = new BNode<K, V>(rhs.root->key, rhs.root->val, rhs.root->N);
copy(rhs.root, root);
}
return *this;
}
~BST() //析构
{
debuild(root);
}
int size(); //返回元素个数
std::pair<bool, V> get(const K &keys); //返回是否含有键,及键对应的值
bool contains(const K &keys); //是否包含值
void put(const K &keys, const V &vals); //插入键值对
K max(); //最大键
K min(); //最小键
std::pair<bool, K> floor(const K &keys); //小于等于keys的最大键
std::pair<bool, K> ceiling(const K &keys); //大于等于keys的最小键
std::pair<bool, K> select(int k); //返回排名第k个键
int rank(const K &keys); // keys的排名
void del(const K &keys); //删除keys键值对
void delMin(); //删除最小值
void delMax(); //删除最大值
std::vector<K> keyVec(); //返回排序后的所有键
std::vector<K> keyVec(const K &keysLo, const K &keysHi); //返回[keysLo, keysHi]之间的键
private:
void debuild(BNode<K, V> *x); //递归删除节点
void copy(BNode<K, V> *oriT, BNode<K, V> *newT); //递归拷贝节点
int size(BNode<K, V> *x);
std::pair<bool, V> get(BNode<K, V> *x, const K &keys);
bool contains(BNode<K, V> *x, const K &keys);
BNode<K, V> *put(BNode<K, V> *x, const K &keys, const V &vals);
BNode<K, V> *min(BNode<K, V> *x);
BNode<K, V> *max(BNode<K, V> *x);
BNode<K, V> *floor(BNode<K, V> *x, const K &key);
BNode<K, V> *ceiling(BNode<K, V> *x, const K &key);
BNode<K, V> *select(BNode<K, V> *x, int k);
int rank(BNode<K, V> *x, const K &keys);
BNode<K, V> *del(BNode<K, V> *x, const K &keys);
BNode<K, V> *delMin(BNode<K, V> *x);
BNode<K, V> *divMin(BNode<K, V> *x); //分离最小值节点,不delete
BNode<K, V> *delMax(BNode<K, V> *x);
BNode<K, V> *divMax(BNode<K, V> *x); //分离最大值节点,不delete
void keyVec(BNode<K, V> *x, std::vector<K> &queue, const K &keysLo, const K &keysHi);
BNode<K, V> *root = nullptr; //二叉树根节点
};
template <typename K, typename V>
void ST::BST<K, V>::debuild(BNode<K, V> *x)
{
if (x == nullptr)
{
return;
}
BNode<K, V> *tempL = x->left;
BNode<K, V> *tempR = x->right;
delete x;
debuild(tempL);
debuild(tempR);
}
template <typename K, typename V>
void ST::BST<K, V>::copy(BNode<K, V> *oriT, BNode<K, V> *newT)
{
if (oriT)
{
if (oriT->left)
{
newT->left = new BNode<K, V>(oriT->left->key, oriT->left->val, oriT->left->N);
}
if (oriT->right)
{
newT->right = new BNode<K, V>(oriT->right->key, oriT->right->val, oriT->right->N);
}
copy(oriT->left, newT->left);
copy(oriT->right, newT->right);
}
else
{
return;
}
}
template <typename K, typename V>
int ST::BST<K, V>::size()
{
return size(root);
}
template <typename K, typename V>
int ST::BST<K, V>::size(BNode<K, V> *x)
{
if (x == nullptr)
{
return 0;
}
else
{
return x->N;
}
}
template <typename K, typename V>
std::pair<bool, V> ST::BST<K, V>::get(const K &keys)
{
return get(root, keys);
}
template <typename K, typename V>
std::pair<bool, V> ST::BST<K, V>::get(BNode<K, V> *x, const K &keys)
{
if (x == nullptr)
{
return std::pair<bool, V>(false, V());
}
if (keys < x->key)
{
return get(x->left, keys);
}
else if (keys > x->key)
{
return get(x->right, keys);
}
else
{
return std::pair<bool, V>(true, x->val);
}
}
template <typename K, typename V>
bool ST::BST<K, V>::contains(const K &keys)
{
return contains(root, keys);
}
template <typename K, typename V>
bool ST::BST<K, V>::contains(BNode<K, V> *x, const K &keys)
{
if (x == nullptr)
{
return false;
}
if (keys < x->key)
{
return contains(x->left, keys);
}
else if (keys > x->key)
{
return contains(x->right, keys);
}
else
{
return true;
}
}
template <typename K, typename V>
void ST::BST<K, V>::put(const K &keys, const V &vals)
{
root = put(root, keys, vals);
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::put(BNode<K, V> *x, const K &keys, const V &vals)
{
if (x == nullptr)
{
return new BNode<K, V>(keys, vals, 1);
}
if (keys < x->key)
{
x->left = put(x->left, keys, vals);
}
else if (keys > x->key)
{
x->right = put(x->right, keys, vals);
}
else
{
x->val = vals;
}
x->N = size(x->left) + size(x->right) + 1;
return x;
}
template <typename K, typename V>
K ST::BST<K, V>::min()
{
return min(root)->key;
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::min(BNode<K, V> *x)
{
if (x->left == nullptr)
{
return x;
}
return min(x->left);
}
template <typename K, typename V>
K ST::BST<K, V>::max()
{
return max(root)->key;
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::max(BNode<K, V> *x)
{
if (x->right == nullptr)
{
return x;
}
return max(x->right);
}
template <typename K, typename V>
std::pair<bool, K> ST::BST<K, V>::floor(const K &keys)
{
BNode<K, V> *x = floor(root, keys);
if (x == nullptr)
{
return std::pair<bool, K>(false, K());
}
return std::pair<bool, K>(true, x.key);
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::floor(BNode<K, V> *x, const K &keys)
{
if (x == nullptr)
{
return nullptr;
}
else if (keys == x->key)
{
return x;
}
else if (keys < x->key)
{
return floor(x.left, keys);
}
else
{
BNode<K, V> *t = floor(x.right, keys);
if (t != nullptr)
{
return t;
}
else
{
return x;
}
}
}
template <typename K, typename V>
std::pair<bool, K> ST::BST<K, V>::ceiling(const K &keys)
{
BNode<K, V> *x = ceiling(root, keys);
if (x == nullptr)
{
return std::pair<bool, K>(false, K());
}
return std::pair<bool, K>(true, x.key);
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::ceiling(BNode<K, V> *x, const K &keys)
{
if (x == nullptr)
{
return nullptr;
}
else if (keys == x->key)
{
return x;
}
else if (keys > x->key)
{
return ceiling(x->right, keys);
}
else
{
BNode<K, V> *t = ceiling(x->left, keys);
if (t != nullptr)
{
return t;
}
else
{
return x;
}
}
}
template <typename K, typename V>
std::pair<bool, K> ST::BST<K, V>::select(int k)
{
BNode<K, V> *x = select(root, k);
if (x)
{
return std::pair<bool, K>(true, x.key);
}
else
{
return std::pair<bool, K>(true, K());
}
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::select(BNode<K, V> *x, int k)
{
if (x == nullptr)
{
return nullptr;
}
int t = size(x->left);
if (t > k)
{
return select(x->left, k);
}
else if (t < k)
{
return select(x->right, k - t - 1);
}
else
{
return x;
}
}
template <typename K, typename V>
int ST::BST<K, V>::rank(const K &keys)
{
return rank(root, keys);
}
template <typename K, typename V>
int ST::BST<K, V>::rank(BNode<K, V> *x, const K &keys)
{
if (x == nullptr)
{
return 0;
}
if (keys < x->key)
{
return rank(x->left, keys);
}
else if (keys > x->key)
{
return 1 + size(x->left) + rank(x->right, keys);
}
else
{
return size(x->left);
}
}
template <typename K, typename V>
void ST::BST<K, V>::delMin()
{
root = delMin(root);
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::delMin(BNode<K, V> *x)
{
if (x->left == nullptr)
{
BNode<K, V> *temp = x->right;
delete x;
x = nullptr;
return temp;
}
x->left = delMin(x->left);
x->N = size(x->left) + size(x->right) + 1;
return x;
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::divMin(BNode<K, V> *x)
{
if (x->left == nullptr)
{
BNode<K, V> *temp = x->right;
return temp;
}
x->left = divMin(x->left);
x->N = size(x->left) + size(x->right) + 1;
return x;
}
template <typename K, typename V>
void ST::BST<K, V>::delMax()
{
root = delMax(root);
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::delMax(BNode<K, V> *x)
{
if (x->right == nullptr)
{
BNode<K, V> *temp = x->left;
delete x;
x = nullptr;
return temp;
}
x->right = delMax(x->right);
x->N = size(x->left) + size(x->right) + 1;
return x;
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::divMax(BNode<K, V> *x)
{
if (x->right == nullptr)
{
BNode<K, V> *temp = x->left;
return temp;
}
x->right = divMax(x->right);
x->N = size(x->left) + size(x->right) + 1;
return x;
}
template <typename K, typename V>
void ST::BST<K, V>::del(const K &keys)
{
root = del(root, keys);
}
template <typename K, typename V>
BNode<K, V> *ST::BST<K, V>::del(BNode<K, V> *x, const K &keys)
{
if (x == nullptr)
{
return nullptr;
}
if (keys < x->key)
{
x->left = del(x->left, keys);
}
else if (keys > x->key)
{
x->right = del(x->right, keys);
}
else
{
if (x->right == nullptr)
{
BNode<K, V> *temp = x->left;
delete x;
return temp;
}
else if (x->left = nullptr)
{
BNode<K, V> *temp = x->right;
delete x;
return temp;
}
BNode<K, V> *temp = x;
if (temp->left->N > temp->right->N)
{
x = max(temp->left);
x->left = divMax(temp->left);
x->right = temp->right;
delete temp;
temp = nullptr;
}
else
{
x = min(temp->right);
x->right = divMin(temp->right);
x->left = temp->left;
delete temp;
temp = nullptr;
}
}
x->N = size(x->left) + size(x->right) + 1;
return x;
}
template <typename K, typename V>
std::vector<K> ST::BST<K, V>::keyVec()
{
return keyVec(min(), max());
}
template <typename K, typename V>
std::vector<K> ST::BST<K, V>::keyVec(const K &keysLo, const K &keysHi)
{
std::vector<K> queue;
queue.reserve(rank(root, keysHi) - rank(root, keysLo) + 1);
keyVec(root, queue, keysLo, keysHi);
return queue;
}
template <typename K, typename V>
void ST::BST<K, V>::keyVec(BNode<K, V> *x, std::vector<K> &queue, const K &keysLo, const K &keysHi)
{
if (x == nullptr)
{
return;
}
if (keysLo < x->key)
{
keyVec(x->left, queue, keysLo, keysHi);
}
if (keysLo <= x->key && keysHi >= x->key)
{
queue.push_back(x->key);
}
if (keysHi > x->key)
{
keyVec(x->right, queue, keysLo, keysHi);
}
}
} // namespace ST
#endif