treap树的插入与删除

为避免普通的二叉搜索树在最坏情况下退化为单链表,引入了使二叉搜索树近似保持平衡的treap树,treap是一棵二叉搜索树,和普通的二叉搜索树不同的是,treap树每一个节点有一个附加的数据域pri,各节点的pri满足最大或最小堆序,treap树各节点按关键码组织为二叉搜索树,按pri数据域组织为最小堆或最大堆,只要在插入或删除时保证堆性质不被破坏,就能使二叉搜索树尽可能保持近似平衡,保证搜索效率,treap树就是二叉搜索树和堆合二为一的产物

treap树删除:

以最小堆序为例

设被删节点为p,若p为叶节点直接删除,结束。若p只有一颗子树,删除p,并把唯一一棵子树链接至p父节点对应指针域,结束.若p有两棵子树,在两棵子树的根节点中选择pri值较小的节点,若该节点是p左子女,对p右单旋转,若该节点是p的右子女,对p左单旋转,旋转完毕后,p应仍然指向旋转前它指向的节点,然后对p继续实行以上操作直到结束为止

treap树插入

以最小堆序为例

根据要插入的关键码用二叉搜索树插入算法往treap树中插入新节点,然后为新节点生成随机的pri值

令p为新插入的节点,算法开始

若p为根节点,结束算法,否则若p的pri值大于等于p的父节点pri值,则结束算法,否则,若p为父节点的左子女,对父节点作右单旋转,若p为父节点右子女,对父节点作左单旋转,旋转结束后,应令p指向旋转前p指向的节点。然后对p重复前述操作直到结束为止

仔细想想不难证明,插入删除算法都能保证treap树的性质(二叉搜索树和堆)不被破坏

以下是实现treap树的C++代码:

#include <iostream>
#include <stack>
#include <random>
#include <vector>
using namespace std;

template <typename T>
struct TreapTreeNode   //Treap树节点定义
{
	T data_field;
	unsigned long long priority = 0;   //堆中优先级
	TreapTreeNode* left_child = nullptr;
	TreapTreeNode* right_child = nullptr;
	TreapTreeNode(const T& d, unsigned long long p) :data_field(d), priority(p) {}
};


template <typename T>
void leftRotate(TreapTreeNode<T>* ptr)
{
	TreapTreeNode<T>* p = ptr->right_child;
	ptr->right_child = p->left_child;
	p->left_child = ptr;
	ptr = p;
}

template <typename T>
void rightRotate(TreapTreeNode<T>* ptr)
{
	TreapTreeNode<T>* p = ptr->left_child;
	ptr->left_child = p->right_child;
	p->right_child = ptr;
	ptr = p;
}

template <typename T>
struct JudgeResult  //对二叉树的判断结果
{
	bool isTreap = true;  //是否为二叉搜索树
	T max_value_in_Treap;  //二叉搜索树中最大节点值
	T min_value_in_Treap;  //二叉搜索树中的最小节点值
};

template <typename T>
class TreapTree
{
public:
	bool insert(const T& key);   //插入关键码
	bool remove(const T& key);   //移除关键码
	bool judgeTreap() { return isTreap(root).isTreap; }
	TreapTree() = default;
	TreapTree(unsigned long long seed) :make_priority(seed) {}
	~TreapTree() { destory(root); }
private:
	JudgeResult<T> isTreap(TreapTreeNode<T>* root);  //判断当前二叉树是否为Treap树
	void destory(TreapTreeNode<T>* root)
	{
		if (root != nullptr)
		{
			destory(root->left_child);
			destory(root->right_child);
			delete root;
		}
	}
	TreapTreeNode<T>* root = nullptr;   //Treap树根节点
	default_random_engine make_priority;   //为新插入节点生成堆优先级的随机数引擎
};


template <typename T>
bool TreapTree<T>::insert(const T& key)
{
	stack<TreapTreeNode<T>*> work_stack;
	TreapTreeNode<T>* cur = root;
	if (cur == nullptr)
	{
		root = new TreapTreeNode<T>(key, make_priority());
		return true;
	}
	else
	{
		while (cur != nullptr)
		{
			if (key == cur->data_field)
			{
				return false;
			}

			if (key > cur->data_field)
			{
				work_stack.push(cur);
				cur = cur->right_child;
			}
			else
			{
				work_stack.push(cur);
				cur = cur->left_child;
			}
		}
	}

	if (key < work_stack.top()->data_field)
	{
		cur = work_stack.top()->left_child = new TreapTreeNode<T>(key, make_priority());
	}
	else
	{
		cur = work_stack.top()->right_child = new TreapTreeNode<T>(key, make_priority());
	}

	while (true)
	{
		if (cur->priority < work_stack.top()->priority)
		{
			if (work_stack.top()->left_child == cur)
			{
				rightRotate(work_stack.top());
			}
			else
			{
				leftRotate(work_stack.top());
			}

			work_stack.pop();
			if (work_stack.empty() == false)
			{
				if (cur->data_field < work_stack.top()->data_field)
				{
					work_stack.top()->left_child = cur;
				}
				else
				{
					work_stack.top()->right_child = cur;
				}
			}
			else
			{
				root = cur;
				return true;
			}
		}
		else
		{
			return true;
		}
	}
}

template <typename T>
void process(TreapTreeNode<T>* cur, TreapTreeNode<T>* parent, TreapTreeNode<T>* value)
{
	if (parent->left_child == cur)
	{
		parent->left_child = value;
	}
	else
	{
		parent->right_child = value;
	}
}

template <typename T>
bool TreapTree<T>::remove(const T& key)
{
	TreapTreeNode<T>* cur = root;
	TreapTreeNode<T>* parent = nullptr;

	while (cur != nullptr)
	{
		if (cur->data_field == key)
		{
			break;
		}

		parent = cur;
		if (key < cur->data_field)
		{
			cur = cur->left_child;
		}
		else
		{
			cur = cur->right_child;
		}
	}

	if (cur == nullptr)
	{
		return false;
	}

	while (true)
	{
		if (cur->left_child == nullptr)
		{
			if (cur->right_child == nullptr)
			{
				if (parent != nullptr)
				{
					process(cur, parent, static_cast<TreapTreeNode<T>*>(nullptr));
					delete cur;
				}
				else
				{
					root = nullptr;
				}
			}
			else
			{
				if (parent != nullptr)
				{
					process(cur, parent, cur->right_child);
				}
				else
				{
					root = cur->right_child;
				}
				delete cur;
			}
			return true;
		}
		else
		{
			if (cur->right_child == nullptr)
			{
				if (parent != nullptr)
				{
					process(cur, parent, cur->left_child);
				}
				else
				{
					root = cur->left_child;
				}
				delete cur;
				return true;
			}
			else
			{
				TreapTreeNode<T>* p = nullptr;
				if (cur->left_child->priority <= cur->right_child->priority)
				{
					p = cur->left_child;
					rightRotate(cur);
				}
				else
				{
					p = cur->right_child;
					leftRotate(cur);
				}

				if (parent != nullptr)
				{
					process(cur, parent, p);
				}
				else
				{
					root = p;
				}
				parent = p;
			}
		}
	}
}

template <typename T>
JudgeResult<T> TreapTree<T>::isTreap(TreapTreeNode<T>* root)
{
	if (root == nullptr)
	{
		return JudgeResult<T>();
	}

	JudgeResult<T> result;
	if (root->left_child != nullptr)
	{
		JudgeResult<T> temp = isTreap(root->left_child);
		if (temp.isTreap == true && temp.max_value_in_Treap < root->data_field && root->priority <= root->left_child->priority)
		{
			result.min_value_in_Treap = temp.min_value_in_Treap;
		}
		else
		{
			result.isTreap = false;
		}
	}
	else
	{
		result.min_value_in_Treap = root->data_field;
	}

	if (root->right_child != nullptr)
	{
		JudgeResult<T> temp = isTreap(root->right_child);
		if (temp.isTreap == true && temp.min_value_in_Treap > root->data_field && root->priority <= root->right_child->priority)
		{
			result.max_value_in_Treap = temp.max_value_in_Treap;
		}
		else
		{
			result.isTreap = false;
		}
	}
	else
	{
		result.max_value_in_Treap = root->data_field;
	}
	return result;
}

int main()
{
	const int N = 2000;
	TreapTree<int> test_obj;
	vector<size_t> data(N);

	for (size_t i = 0; i < N; ++i)
		data[i] = i + 1;
	shuffle(data.begin(), data.end(), default_random_engine());
	for (const int& i : data)
	{
		cout << "在Treap树中插入关键码" << i << endl;
		test_obj.insert(i);
		if (!test_obj.judgeTreap())
		{
			cout << "ERROR:当前树不为Treap树" << endl;
			exit(-1);
		}
		else
		{
			cout << "当前树为Treap树" << endl;
			cout << endl;
		}
	}

	for (const int& i : data)
	{
		cout << "在Treap树中删除关键码" << i << endl;
		test_obj.remove(i);
		if (!test_obj.judgeTreap())
		{
			cout << "ERROR:当前树不为Treap树" << endl;
			exit(-1);
		}
		else
		{
			cout << "当前树为Treap树" << endl;
			cout << endl;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值