Treap 树

来源:互联网 发布:手机淘宝小二怎么联系 编辑:程序博客网 时间:2024/05/21 10:36

Treap树堆 是一种 随机平衡二叉树。

相对于正正规规的AVL树,倒是灵活了许多。

Treap 也有旋转模式,但是只有单选转,而且Treap的旋转,怎么旋转,该不该旋转完全是随机化的,这样子在大大减少了编码量的同时,相对也把效率给提了上去。在最差情况下也比最差情况下的朴素 BST 好


代码参考 《Data Structure and Algorithm Analysis in C》


结构体部分:

typedef struct Treap * Node;  Node root = 0;        //保存根节点 Node NulNode = 0;     //传说中的标记节点,不使用NULL是因为怕出错,而且代码写起来较方便                      //可以理解为代替空指针防止出错的自定义指针 struct Treap{  Node left, right;   //子节点  int key;            //值,可自定义   int priority;       //优先级,随机生成的一个数,后面会用到。 };


左右旋转

Node L_Rotate(Node K2){Node K1 = K2 -> left;K2 -> left = K1 -> right;K1 -> right = K2;return K1;}Node R_Rotate(Node K2){Node K1 = K2 -> right;K2 -> right = K1 -> left;K1 -> left = K2;return K1;}



插入其实也不难,记得每次执行插入后旋转一次

Node insert(Node T,int key){// 采用递归写法  int num = rand() % 10086383;  //产生一个随机数 if(T == NulNode)              //如果树为空,则新建 {T = new Treap();T -> key = key;T -> priority = num;T -> left = T -> right = NulNode;  //初始化 return T;}else{if (key > T->key)      //插入值比当前大,往右。 {T->right = insert(T->right , key);  //注意! T->right = insert(T->right,key) 左边right不能丢 if(T -> left -> priority   <   T -> right -> priority)   T = L_Rotate(T);    //插入后旋转 } else if (key < T->key){T->left = insert(T->left , key);if(T -> left -> priority   >   T -> right -> priority)   T = R_Rotate(T);}}return T;}


删除略有些麻烦。

Node Remove(Node T , int key){if(T!=NulNode)  //如果不为空 {if (key < T ->key)  T->left = Remove(T->left,key);    else if (key > T->key)  T->right = Remove(T->right,key); else{if(T->left->priority < T -> right -> priority)     T = L_Rotate(T);else   T = R_Rotate(T);  //调整到所求点为叶节点 if(T != NulNode)  T = Remove(T , key);else{ delete T -> left;   //要删的节点 仍有左右子树NulNode,                    //为了返回值时,好处理,所以用旋转把key所在地方变为NulNode的子节点后删除。 T->left = NulNode; }}}return T;}



0 0
原创粉丝点击