SizeBalancedTree C++实现

SBT

SizeBalancedTree,SBT也是一种自平衡二叉搜索树,它的均摊时间复杂度不差于红黑树,实现起来比红黑树简单很多,它的旋转方式与AVL树一样,它的平衡条件靠的是每个节点的侄子节点不大于叔叔节点, 旋转的方式与AVL相同。


n1上的节点数量 和 n2上的节点数量 都不大于u2上的节点数量
n3上的节点数量 和 n4上的节点数量 都不大于u1上的节点数量

每个节点都符合以上条件就认为这棵树平衡。

在这里插入图片描述

红黑树相对与AVL树高效一点,AVL在删除时,每次删除节点都可能导致父节点乃至根节点这条链上的所有节点都失衡,所以最坏情况需要logN次的旋转,红黑树却只需要有限几次。SBT的平衡调整是递归进行的,但也只需有限几次的旋转就能恢复平衡。


SBT的特点

  • SBT在删除的时候,可以不用进行旋转调整树的高度,即使退化成链状也无所谓,调整操作放到添加节点时。

  • SBT每个节点上保存的size可以很好的解决第k大问题。

  • SBT实现简单,易修改


C++实现

#pragma once

#include <iostream>
#include <stack>
#include <cassert>
#include <vector>
#include <string>
#include <stdlib.h>
#include <queue>


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;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

necesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值