一、全部代码
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
//Treap结构
struct TreapNode
{
TreapNode *pLeft, *pRight;
int value, fix;
};
//左旋
void TreapLeftRotate(TreapNode* &pCur){
//首先,找到当前根节点的右子树
TreapNode* rightChild = pCur->pRight;
//然后把右子树的左孩子接到当前根节点的右子树
pCur->pRight = rightChild->pLeft;
//再设右子树的左孩子为当前根节点
rightChild->pLeft = pCur;
pCur = rightChild;
}
//右旋
void TreapRightRotate(TreapNode* & pCur){
//首先,找到当前根节点左子树
TreapNode* leftChild = pCur->pLeft;
//然后,把左子树的右孩子接到当前根节点的左子树
pCur->pLeft = leftChild->pRight;
//再设左子树的右孩子为当前根节点
leftChild->pRight = pCur;
pCur = leftChild;
}
//插入
void TreapInsert(TreapNode* &pCur, int newV){
//要插入首先要找到插入的位置,如果要插入的节点为NULL,说明到达了该插入的时机
if(pCur == NULL){
pCur = new TreapNode; //开辟空间
pCur->value = newV; //赋值
pCur->pLeft = NULL; //新节点左子树为NULL
pCur->pRight = NULL; //新节点右子树为NULL
pCur->fix = rand()%10000; //给予一个修正随机数
}
//如果当前节点的值比newV大,就往左找
else if(newV < pCur->value){
TreapInsert(pCur->pLeft, newV);//向左递归插入
//插入之后,要进行fix的修正,因为是向左子树递归,所以判断左子树的fix大小并右旋即可
if(pCur->pLeft->fix < pCur->fix){
TreapRightRotate(pCur);
}
}
//同上
else{
TreapInsert(pCur->pRight, newV);
if(pCur->pRight->fix < pCur->fix){
TreapLeftRotate(pCur);
}
}
}
//查找
TreapNode* TreapSearch(TreapNode* pCur, int totalValue){
//相等说明找到了
if(pCur == NULL) return NULL;
if(pCur->value == totalValue){
return pCur;
}
//不相等就判断他在当前节点的左边还是右边
else if(pCur->value < totalValue)
return TreapSearch(pCur->pRight, totalValue);
else
return TreapSearch(pCur->pLeft, totalValue);
}
//删除
void TreapDelete(TreapNode* &pCur, int deleteValue){
//如果相等说明有这个值,进行删除
if(pCur->value == deleteValue){
//如果是只有一个节点或者没有节点的情况
if(pCur->pLeft == NULL || pCur->pRight == NULL){
TreapNode* deleteNode = pCur; //记录要删除的节点
//判断左右子树哪个不是NULL,直接将它放在删除节点的位置
if(pCur->pLeft != NULL){
pCur = pCur->pLeft;
}
else{
pCur = pCur->pRight;
}
delete deleteNode; //删除节点
}
//如果是有两个结点的情况
else{
//左子树fix值比右子树fix值小
if(pCur->pLeft->fix < pCur->pRight->fix){
TreapRightRotate(pCur);//右旋
TreapDelete(pCur->pRight, deleteValue); //由于右旋将要删除的元素移动到了右侧,所以向右继续递归删除
}
else{
TreapLeftRotate(pCur);
TreapDelete(pCur->pLeft, deleteValue);
}
}
}
//如果不相等就继续找
else if(pCur->value < deleteValue)
TreapDelete(pCur->pRight, deleteValue);
else
TreapDelete(pCur->pLeft, deleteValue);
}
//先序遍历
void preOrder(TreapNode* pCur){
if(pCur != NULL){
cout << "(" << pCur->value << " ," << pCur->fix << ")";
preOrder(pCur->pLeft);
preOrder(pCur->pRight);
}
}
//中序遍历
void inOrder(TreapNode* pCur){
if(pCur == NULL){
inOrder(pCur->pLeft);
cout << "(" << pCur->value << " ," << pCur->fix << ")";
inOrder(pCur->pRight);
}
}
TreapNode *root=NULL;
int main()
{
srand((unsigned)time(0));
int data[]={1,2,3,4,5,6,7,8,9,10,2,5,6};
int n=sizeof(data)/sizeof(int),i,cnt=0;
for(i=0;i<n;i++)
{
//先查找是否存在
TreapNode* pFound = TreapSearch(root, data[i]);
//不存在就插入
if(pFound==NULL)
{
TreapInsert(root,data[i]);
cnt++;//记录元素个数
}
}
//删除之前的树
cout << "删除之前的树:";
inOrder(root);//中序遍历
cout << endl;
preOrder(root); //先序遍历
TreapDelete(root,4); //删除一个4测试
//删除之后的树
cout<<"\n"<<cnt<<endl;
cout << "删除之后的树:";
inOrder(root);
cout<<endl;
preOrder(root);
return 0;
}
二、运行结果