为避免普通的二叉搜索树在最坏情况下退化为单链表,引入了使二叉搜索树近似保持平衡的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;
}