SizeBalancedTree,SBT也是一种自平衡二叉搜索树,它的均摊时间复杂度不差于红黑树,实现起来比红黑树简单很多,它的旋转方式与AVL树一样,它的平衡条件靠的是每个节点的侄子节点不大于叔叔节点, 旋转的方式与AVL相同。
n1上的节点数量 和 n2上的节点数量 都不大于u2上的节点数量
n3上的节点数量 和 n4上的节点数量 都不大于u1上的节点数量
每个节点都符合以上条件就认为这棵树平衡。
红黑树相对与AVL树高效一点,AVL在删除时,每次删除节点都可能导致父节点乃至根节点这条链上的所有节点都失衡,所以最坏情况需要logN次的旋转,红黑树却只需要有限几次。
SBT的平衡调整是递归进行的,但也只需有限几次的旋转就能恢复平衡。
SBT的特点
-
SBT在删除的时候,可以不用进行旋转调整树的高度,即使退化成链状也无所谓,调整 *** 作放到添加节点时。
-
SBT每个节点上保存的size可以很好的解决第k大问题。
-
SBT实现简单,易修改
C++实现
#pragma once
#include
#include
#include
#include
#include
#include
#include
using namespace std;
template<class T>
struct CMP
{
bool operator()(const T& t1, const T& t2)
{
return t1 < t2;
}
};
template<class K, class V, class CMP>
class SizeBalancedTreeMap
{
struct TreeNode
{
TreeNode(const K& _key, const V& _val) :key(_key), val(_val), size(1), left(nullptr), right(nullptr) {}
size_t getSize()
{
if (!this) return 0;
return size;
}
void reSize()
{
if (!this) return;
size_t leftSize = this->left->getSize();
size_t rightSize = this->right->getSize();
size = leftSize + rightSize + 1;
}
TreeNode& operator=(const TreeNode& node)
{
if (this != &node)
{
this->key = node.key;
this->val = node.val;
}
return *this;
}
TreeNode* left;
TreeNode* right;
size_t size;
K key;
V val;
};
public:
SizeBalancedTreeMap() :root(nullptr) {}
~SizeBalancedTreeMap() { clear(); }
void put(const K& key, const V& val)
{
TreeNode* find = findLast(key);
if (find && find->key == key) //更新val
{
find->val = val;
}
else {
this->root = add(root, key, val);
}
}
bool containKey(const K& key)
{
if (empty()) return false;
CMP cmp;
TreeNode* cur = root;
while (cur)
{
if (cmp(cur->key, key))
cur = cur->right;
else if (cmp(key, cur->key))
cur = cur->left;
else
return true;
}
return false;
}
void remove(const K& key)
{
if (containKey(key)) {
this->root = del(root, key);
}
}
size_t size()
{
return empty() ? 0 : root->size;
}
bool empty()
{
return nullptr == root;
}
void clear()
{
}
private:
TreeNode* del(TreeNode* cur, const K& key)
{
CMP cmp;
cur->size--;
if (cmp(cur->key, key))
{
cur->right = del(cur->right, key);
}
else if (cmp(key, cur->key))
{
cur->left = del(cur->left, key);
}
else {
if (cur->left == nullptr && cur->right == nullptr) //度为0
{
delete cur;
cur = nullptr;
}
else if (cur->left != nullptr && cur->right == nullptr) //度为1
{
TreeNode* tmp = cur;
cur = cur->left;
delete tmp;
}
else if (cur->left == nullptr && cur->right != nullptr) //度为1
{
TreeNode* tmp = cur;
cur = cur->right;
delete tmp;
}
else //度为2
{
TreeNode* prev = nullptr;
TreeNode* replace = cur->left;
//replace->size--;
while ( replace && replace->right)
{
replace->size--;
prev = replace;
replace = replace->right;
}
if (prev)
{
prev->right = replace->left;
replace->left = cur->left;
}
replace->right = cur->right;
replace->reSize();
delete cur;
cur = replace;
}
}
return cur;
}
TreeNode* add(TreeNode* cur, const K& key, const V& val)
{
if (!cur) return new TreeNode(key, val);
//CMP cmp;
cur->size++; //沿途增加size
if (cur->key > key) //递归调整
cur->left = add(cur->left, key, val); //添加到左子树
else
cur->right = add(cur->right, key, val); //添加到右子树
return maintain(cur);
}
TreeNode* findLast(const K& key)
{
if (empty()) return nullptr;
CMP cmp;
TreeNode* cur = root;
while (cur)
{
if (cmp(cur->key, key))
{
if (cur->right)
cur = cur->right;
else
break;
}
else if (cmp(key, cur->key))
{
if (cur->left)
cur = cur->left;
else
break;
}
else
{
break;
}
}
return cur;
}
//递归递归maintain进行调整
TreeNode* maintain(TreeNode* cur)
{
if (!cur) return cur;
TreeNode* left = cur->left;
TreeNode* right = cur->right;
size_t leftSize = left->getSize();
size_t rightSize = right->getSize();
if (left && left->left && left->left->size > rightSize) //LL
{
cur = right_rotate(cur);
cur->right = maintain(cur->right);
cur = maintain(cur);
}
else if (left && left->right && left->right->size > rightSize) //LR
{
cur->left = left_rotate(cur->left);
cur = right_rotate(cur);
cur->left = maintain(cur->left);
cur->right = maintain(cur->right);
cur = maintain(cur);
}
else if (right && right->right && right->right->size > leftSize) //RR
{
cur = left_rotate(cur);
cur->left = maintain(cur->left);
cur = maintain(cur);
}
else if (right && right->left && right->left->size > leftSize) //RL
{
cur->right = right_rotate(cur->right);
cur = left_rotate(cur);
cur->left = maintain(cur->left);
cur->right = maintain(cur->right);
cur = maintain(cur);
}
return cur;
}
TreeNode* right_rotate(TreeNode* node) //旋转和重新挂接
{
TreeNode* newRoot = node->left;
node->left = newRoot->right;
newRoot->right = node;
newRoot->size = node->size;
node->reSize();
return newRoot;
}
TreeNode* left_rotate(TreeNode* node)
{
TreeNode* newRoot = node->right;
node->right = newRoot->left;
newRoot->left = node;
newRoot->size = node->size;
node->reSize();
return newRoot;
}
public:
//打印中序遍历
void show()
{
if (empty()) return;
inorder(root);
}
void inorder(TreeNode* root)
{
if (!root)
return;
inorder(root->left);
cout << root->key << " ";
inorder(root->right);
}
//中序遍历判断是否有序
bool isOrder()
{
if (empty()) return true;
TreeNode* cur = root;
stack<TreeNode*> st;
int num = INT_MIN;
bool flag1 = true;
bool flag2 = false;
while (!st.empty() || cur) {
if (cur) {
st.push(cur);
cur = cur->left;
}
else {
cur = st.top();
st.pop();
if (flag1)
{
num = cur->key;
flag2 = true;
flag1 = false;
}
else if (flag2)
{
if (num > cur->key)
assert(0);
num = cur->key;
}
cur = cur->right;
}
}//end of while
return true;
}
//逐层打印
void printLevel()
{
if (empty()) return;
std::queue<TreeNode*> que1;
std::queue<TreeNode*> que2;
vector<vector<TreeNode*>> v;
vector<TreeNode*> tmp;
TreeNode* cur = root;
que1.push(cur);
while (!que1.empty() || !que2.empty())
{
while (!que1.empty())
{
cur = que1.front();
que1.pop();
tmp.push_back(cur);
if (cur->left)
que2.push(cur->left);
if (cur->right)
que2.push(cur->right);
}
if (!tmp.empty())
v.push_back(tmp);
tmp.clear();
while (!que2.empty())
{
cur = que2.front();
que2.pop();
tmp.push_back(cur);
if (cur->left)
que1.push(cur->left);
if (cur->right)
que1.push(cur->right);
}
if (!tmp.empty())
v.push_back(tmp);
tmp.clear();
}
for (const vector<TreeNode*>& tmp : v)
{
for (TreeNode* node : tmp) {
cout << node->key << " ";
}
cout << "--------------------\n";
}
}
//测试 打印最大depth
void printHight()
{
cout << endl << "Depth Hight: " << getHight(root) << endl;
}
//打印最小depth
void printLow()
{
cout << endl << "Depth Low: " << getLow(root) << endl;
}
private:
int getHight(TreeNode* root)
{
if (!root) return 0;
int left = getHight(root->left);
int right = getHight(root->right);
return left > right ? left + 1 : right + 1;
}
int getLow(TreeNode* root)
{
if (!root) return 0;
int left = getLow(root->left);
int right = getLow(root->right);
return left > right ? right + 1 : left + 1;
}
private:
TreeNode* root;
};
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)