diff --git a/src/main.cpp b/src/main.cpp index 63ce472..52df895 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,35 +2,148 @@ #include #include #include +#include "vbtree.h" +#include "sbt.h" + using namespace std; using chrono::high_resolution_clock; +int IntCompare(int v1, int v2) +{ + if (v1 > v2) + { + return 1; + } + else if (v1 < v2) + { + return -1; + } + else + { + return 0; + } +} +const ULONG N = 5000000; void Case1() { - std::map m; - + std::map m; - default_random_engine e; - std::uniform_int_distribution<> dist{0, 1000000000}; - double N = 1000000; + default_random_engine e; + std::uniform_int_distribution<> dist{0, 1000000000}; + high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 - high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 + for (ULONG i = 0; i < N; i++) + { + auto v = dist(e); + m[v] = v; + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - for (int i = 0; i < N; i++) - { - auto v = dist(e); - m[v] = v; - } - high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 - - std::cout << (t2 - t1).count() / N << std::endl; - std::cout << "end Push Case Benchmark" << std::endl; + std::cout << (t2 - t1).count() / N << std::endl; + std::cout << "end RBTree Case Benchmark" << std::endl; } -int main(int argc, char *argv[]) { - Case1(); +void Case1_1() +{ + std::map m; + + default_random_engine e; + std::uniform_int_distribution<> dist{0, 1000000000}; + + vector vec; + + for (ULONG i = 0; i < N; i++) + { + auto v = dist(e); + m[v] = v; + vec.push_back(v); + } + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 + + for(auto iter = vec.begin(); iter != vec.end() ; iter++) { + m[*iter]; + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 + + std::cout << (t2 - t1).count() / N << std::endl; + std::cout << "end RBTree Case Benchmark" << std::endl; +} + +void Case2() +{ + VBTree m(IntCompare); + + default_random_engine e; + std::uniform_int_distribution<> dist{0, 1000000000}; + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 + + for (ULONG i = 0; i < N; i++) + { + auto v = dist(e); + m.put(v, v); + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 + + std::cout << (t2 - t1).count() / N << std::endl; + std::cout << "end VBTree Case Benchmark" << std::endl; +} + +void Case2_1() +{ + VBTree m(IntCompare); + + default_random_engine e; + std::uniform_int_distribution<> dist{0, 1000000000}; + + vector vec; + + for (ULONG i = 0; i < N; i++) + { + auto v = dist(e); + m.put(v, v); + vec.push_back(v); + } + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 + + for(auto iter = vec.begin(); iter != vec.end() ; iter++) { + m.get(*iter); + } + + high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 + + std::cout << (t2 - t1).count() / N << std::endl; + std::cout << "end VBTree Case Benchmark" << std::endl; +} + +void Case3() { + BinaryTree tree; + + default_random_engine e; + std::uniform_int_distribution<> dist{0, 1000000000}; + + high_resolution_clock::time_point t1 = high_resolution_clock::now(); //返回时间戳 + + for (ULONG i = 0; i < N; i++) + { + auto v = dist(e); + tree.insert(v); + } + high_resolution_clock::time_point t2 = high_resolution_clock::now(); //返回时间戳 + + std::cout << (t2 - t1).count() / N << std::endl; + std::cout << "end SBT Case Benchmark" << std::endl; +} + +int main(int argc, char *argv[]) +{ + Case2_1(); + // Case1(); } \ No newline at end of file diff --git a/src/sbt.h b/src/sbt.h new file mode 100644 index 0000000..190ecc6 --- /dev/null +++ b/src/sbt.h @@ -0,0 +1,314 @@ + +#include +using namespace std; + +class SBTNode { +public: + //size:子树大小(就是以当前结点为根构成的树有多少结点) + //data:权值,就是树上的结点储存的值 + //value:应该是临时储存权值的 + int data, size, value; + SBTNode * lchild, * rchild, * father; + //构造函数,参数分别为 权值,以当前结点为根的树的大小,父亲结点 + SBTNode(int init_data, int init_size = 0, SBTNode * init_father = NULL); + ~SBTNode(); + //下面依次是 + //二叉排序树的插入,搜索,找前驱,找后继,移除某个度为0或1的结点,移除某个权值的点,找出第k大的元素 + void insert(int value); + SBTNode * search(int value); + SBTNode * predecessor(); + SBTNode * successor(); + void remove_node(SBTNode * delete_node); + bool remove(int value); + int select(int k); +}; + +class BinaryTree { +private: + SBTNode * root; +public: + BinaryTree(); + ~BinaryTree(); + //下面依次是 + //二叉树的插入 查找 删除结点 找出第k大的树,都是以上面的结点类的函数为基础的 + void insert(int value); + bool find(int value); + bool remove(int value); + int select(int k); +}; + +//这里搞了个权值为0的结点,避免在边界情况时对空指针(NULL)进行特判,所以将所有原本指向空指针的情况都改为指向一个 ZPTR,并将其 size 设置为 0,从而降低代码复杂度。 +SBTNode ZERO(0); +SBTNode * ZPTR = &ZERO; + +SBTNode::SBTNode(int init_data, int init_size, SBTNode * init_father) { + data = init_data; + size = init_size; + lchild = ZPTR; + rchild = ZPTR; + father = init_father; +} + +SBTNode::~SBTNode() { + if (lchild != ZPTR) { + delete lchild; + } + if (rchild != ZPTR) { + delete rchild; + } +} + +//左旋:将右孩子变为“根结点”(当前子树的根结点),右孩子的左孩子就变成原来的根结点的右孩子 +//下面注释中:node(原来的根结点)的右孩子用“根结点”来说 +SBTNode * left_rotate(SBTNode * node) { + //用temp保存“根结点” + SBTNode * temp = node->rchild; + //“根结点”的左孩子 变成node(原来的根结点)的右孩子 + node->rchild = temp->lchild; + //更新“根结点”原来的左孩子的父亲为node(原来的根结点) + temp->lchild->father = node; + //node(原来的根结点) 就变成“根结点”的左孩子 + temp->lchild = node; + //“根结点”的父亲更新为node(原来的根结点)的父亲 + temp->father = node->father; + //node(原来的根结点)的父亲更新为“根结点” + node->father = temp; + //“根结点”的大小更新为node(原来的根结点)的大小(这里的大小是以该结点为根构成的树的结点的个数) + temp->size = node->size; + //node(原来的根结点)的大小更新为 它左孩子和右孩子的大小再在上本身1 + node->size = node->lchild->size + node->rchild->size + 1; + //返回左旋后的根结点 + return temp; +} + +//右旋:将左孩子变为“根结点”(当前子树的根结点),左孩子的右孩子就变成原来的根结点的左孩子 +//下面注释中:node(原来的根结点)的左孩子用“根结点”来说 +//反正这里跟上几乎相反 +SBTNode * right_rotate(SBTNode * node) { + //用temp保存“根结点” + SBTNode * temp = node->lchild; + //“根结点”的右孩子 变成node(原来的根结点)的左孩子 + node->lchild = temp->rchild; + //更新“根结点”原来的右孩子的父亲为node(原来的根结点) + temp->rchild->father = node; + //node(原来的根结点) 就变成“根结点”的右孩子 + temp->rchild = node; + //“根结点”的父亲更新为node(原来的根结点)的父亲 + temp->father = node->father; + //node(原来的根结点)的父亲更新为“根结点” + node->father = temp; + //“根结点”的大小更新为node(原来的根结点)的大小(这里的大小是以该结点为根构成的树的结点的个数) + temp->size = node->size; + //node(原来的根结点)的大小更新为 它左孩子和右孩子的大小再在上本身1 + node->size = node->lchild->size + node->rchild->size + 1; + //返回右旋后的根结点 + return temp; +} + +//利用上面的左右旋进行调整的函数 +//flag为false:处理左子树更高的情况,否则处理右子树更高的情况 +//node:要调整的子树的根结点 +SBTNode * maintain(SBTNode * node, bool flag) { + //左子树比右子树高(或者叫深度要深) + if (flag == false) { + //LL型:左子树的左子树的元素个数大于右子树的元素个数,应进行右旋 + if (node->lchild->lchild->size > node->rchild->size) { + //右旋并更新子树的根结点 + node = right_rotate(node); + } + //LR型:左子树的右子树的元素个数大于右子树的元素个数 + //那么先对左子树进行左旋,就变成LL型,再右旋即可 + else if (node->lchild->rchild->size > node->rchild->size) { + //左旋并更新左子树的根结点 + node->lchild = left_rotate(node->lchild); + //右旋并更新根节点 + node = right_rotate(node); + } else { + //说明平衡了,返回根节点 + return node; + } + //右子树比左子树高(或者叫深度要深) + } else { + //RR型:右子树的右子树的元素个数大于左子树的元素个数,应进行左旋 + if (node->rchild->rchild->size > node->lchild->size) { + //左旋并更新根节点 + node = left_rotate(node); + } + //RL型: 右子树的左子树的元素个数大于左子树的元素个数 + //那么先对右子树进行右旋,变成RR型,在左旋即可 + else if (node->rchild->lchild->size > node->lchild->size) { + //右旋并更新左子树的根结点 + node->rchild = right_rotate(node->rchild); + //左旋并更新根节点 + node = left_rotate(node); + } else { + //说明平衡了,返回根节点 + return node; + } + } + //下面为递归调用,因为有时上面的调整过后,左子树和右子树的某个结点还是不平衡 + + //递归调用,处理可能左子树的左子树高度更高的情况 + //false表示左子树较高 + node->lchild = maintain(node->lchild, false); + //其右子树的右子树高度更高的情况 + node->rchild = maintain(node->rchild, true); + //最后再对子树根结点的左右子树递归进行调整 + node = maintain(node, false); + node = maintain(node, true); + //返回调整后的子树的根结点 + return node; +} + +SBTNode * insert(SBTNode * node, int value) { + if (value == node->data) { + return node; + } else { + node->size++; + if (value > node->data) { + if (node->rchild == ZPTR) { + node->rchild = new SBTNode(value, 1, node); + } else { + node->rchild = insert(node->rchild, value); + } + } else { + if (node->lchild == ZPTR) { + node->lchild = new SBTNode(value, 1, node); + } else { + node->lchild = insert(node->lchild, value); + } + } + } + return maintain(node, value > node->data); +} + +SBTNode * SBTNode::search(int value) { + if (data == value) { + return this; + } else if (value > data) { + if (rchild == ZPTR) { + return ZPTR; + } else { + return rchild->search(value); + } + } else { + if (lchild == ZPTR) { + return ZPTR; + } else { + return lchild->search(value); + } + } +} + +SBTNode * SBTNode::predecessor() { + SBTNode * temp = lchild; + while (temp != ZPTR && temp->rchild != ZPTR) { + temp = temp->rchild; + } + return temp; +} + +SBTNode * SBTNode::successor() { + SBTNode * temp = rchild; + while (temp != ZPTR && temp->lchild != ZPTR) { + temp = temp->lchild; + } + return temp; +} + +void SBTNode::remove_node(SBTNode * delete_node) { + SBTNode * temp = ZPTR; + if (delete_node->lchild != ZPTR) { + temp = delete_node->lchild; + temp->father = delete_node->father; + delete_node->lchild = ZPTR; + } + + if (delete_node->rchild != ZPTR) { + temp = delete_node->rchild; + temp->father = delete_node->father; + delete_node->rchild = ZPTR; + } + if (delete_node->father->lchild == delete_node) { + delete_node->father->lchild = temp; + } else { + delete_node->father->rchild = temp; + } + temp = delete_node; + while (temp != NULL) { + temp->size--; + temp = temp->father; + } + delete delete_node; +} + +bool SBTNode::remove(int value) { + SBTNode * delete_node, * current_node; + current_node = search(value); + if (current_node == ZPTR) { + return false; + } + size--; + if (current_node->lchild != ZPTR) { + delete_node = current_node->predecessor(); + } else if (current_node->rchild != ZPTR) { + delete_node = current_node->successor(); + } else { + delete_node = current_node; + } + current_node->data = delete_node->data; + remove_node(delete_node); + return true; +} + +int SBTNode::select(int k) { + //rank表示当前结点在子树的排位 + int rank = lchild->size + 1; + //若rank等于第k小的k,说明就是要找的值,直接返回权值即可 + if (rank == k) { + return data; + }else if (k < rank) { + //小于rank,就表明要找比当前结点更小的,就在左边查找 + return lchild->select(k); + }else{ + //大于就在右边咯 + //这里为什么看k - rank呢,因为我们已经把前rank排除了, + //相当于我们要在右子树(把他当做一颗新的树去查找),所以排位当然要减去rank了 + return rchild->select(k - rank); + } +} + +BinaryTree::BinaryTree() { + root = NULL; +} + +BinaryTree::~BinaryTree() { + if (root != NULL) { + delete root; + } +} + +void BinaryTree::insert(int value) { + if (root == NULL) { + //初始化时只有根结点,所以子树大小为1 + root = new SBTNode(value, 1); + } else { + root = ::insert(root, value); + } +} + +bool BinaryTree::find(int value) { + if (root->search(value) == NULL) { + return false; + } else { + return true; + } +} + +bool BinaryTree::remove(int value) { + return root->remove(value); +} + +int BinaryTree::select(int k) { + return root->select(k); +} diff --git a/src/vbtree.h b/src/vbtree.h new file mode 100644 index 0000000..8eba988 --- /dev/null +++ b/src/vbtree.h @@ -0,0 +1,493 @@ + + +#include +#include +#include +#include + +using namespace std; +using std::cout, std::endl; +using std::tuple, std::make_tuple; + +typedef unsigned long ULONG; + +template +class VBTree +{ +public: + typedef int (*Compare)(TKey, TKey); + struct TreeNode + { + TreeNode *children[2]; + TreeNode *parent; + unsigned long size; + TKey key; + TValue value; + + TreeNode() + { + this->children[0] = NULL; + this->children[1] = NULL; + this->parent = NULL; + this->size = 1; + } + /* data */ + }; + +private: + TreeNode *root; + Compare compare; + ULONG getSize(TreeNode *cur) + { + if (cur == NULL) + { + return 0; + } + return cur->size; + } + + ULONG getChildrenSumSize(TreeNode *cur) + { + return this->getSize(cur->children[0]) + this->getSize(cur->children[1]); + } + + tuple getChildrenSize(TreeNode *cur) + { + return make_tuple(this->getSize(cur->children[0]), this->getSize(cur->children[1])); + } + + void swap_node_kv(TreeNode *n1, TreeNode *n2) + { + TKey tempkey = n1->key; + TValue tempvalue = n1->value; + + n1->key = n2->key; //交换值达到, 相对位移 + n1->value = n2->value; + + n2->key = tempkey; + n2->value = tempvalue; + } + + void lrrotate3(TreeNode *cur) + { + const int l = 1; + const int r = 0; + + TreeNode *movparent = cur->children[l]; + TreeNode *mov = movparent->children[r]; + + this->swap_node_kv(mov, cur); + + cur->children[r] = mov; + mov->parent = cur; + + cur->children[l] = movparent; + movparent->children[r] = NULL; + + cur->children[r] = mov; + mov->parent = cur; + + cur->children[l]->size = 1; + } + + void lrrotate(TreeNode *cur) + { + + const int l = 1; + const int r = 0; + + TreeNode *movparent = cur->children[l]; + TreeNode *mov = movparent->children[r]; + + this->swap_node_kv(mov, cur); //交换值达到, 相对位移 + + if (mov->children[l] != NULL) + { + movparent->children[r] = mov->children[l]; + movparent->children[r]->parent = movparent; + //movparent->children[r].child = l + } + else + { + movparent->children[r] = NULL; + } + + if (mov->children[r] != NULL) + { + mov->children[l] = mov->children[r]; + } + else + { + mov->children[l] = NULL; + } + + if (cur->children[r] != NULL) + { + mov->children[r] = cur->children[r]; + mov->children[r]->parent = mov; + } + else + { + mov->children[r] = NULL; + } + + cur->children[r] = mov; + mov->parent = cur; + + movparent->size = getChildrenSumSize(movparent) + 1; + mov->size = getChildrenSumSize(mov) + 1; + cur->size = getChildrenSumSize(cur) + 1; + } + + void rlrotate3(TreeNode *cur) + { + const int l = 0; + const int r = 1; + + TreeNode *movparent = cur->children[l]; + TreeNode *mov = movparent->children[r]; + + this->swap_node_kv(mov, cur); + + cur->children[r] = mov; + mov->parent = cur; + + cur->children[l] = movparent; + movparent->children[r] = NULL; + + cur->children[r] = mov; + mov->parent = cur; + + cur->children[l]->size = 1; + } + + void rlrotate(TreeNode *cur) + { + const int l = 0; + const int r = 1; + + TreeNode *movparent = cur->children[l]; + TreeNode *mov = movparent->children[r]; + + this->swap_node_kv(mov, cur); + + if (mov->children[l] != NULL) + { + movparent->children[r] = mov->children[l]; + movparent->children[r]->parent = movparent; + } + else + { + movparent->children[r] = NULL; + } + + if (mov->children[r] != NULL) + { + mov->children[l] = mov->children[r]; + } + else + { + mov->children[l] = NULL; + } + + if (cur->children[r] != NULL) + { + mov->children[r] = cur->children[r]; + mov->children[r]->parent = mov; + } + else + { + mov->children[r] = NULL; + } + + cur->children[r] = mov; + mov->parent = cur; + + movparent->size = this->getChildrenSumSize(movparent) + 1; + mov->size = this->getChildrenSumSize(mov) + 1; + cur->size = this->getChildrenSumSize(cur) + 1; + } + + void rrotate3(TreeNode *cur) + { + const int l = 0; + const int r = 1; + // 1 right 0 left + TreeNode *mov = cur->children[l]; + + this->swap_node_kv(mov, cur); + + cur->children[r] = mov; + + cur->children[l] = mov->children[l]; + cur->children[l]->parent = cur; + + mov->children[l] = NULL; + + mov->size = 1; + } + + void rrotate(TreeNode *cur) + { + + const int l = 0; + const int r = 1; + // 1 right 0 left + TreeNode *mov = cur->children[l]; + + this->swap_node_kv(mov, cur); + + // mov->children[l]不可能为nil + mov->children[l]->parent = cur; + + cur->children[l] = mov->children[l]; + + // 解决mov节点孩子转移的问题 + if (mov->children[r] != NULL) + { + mov->children[l] = mov->children[r]; + } + else + { + mov->children[l] = NULL; + } + + if (cur->children[r] != NULL) + { + mov->children[r] = cur->children[r]; + mov->children[r]->parent = mov; + } + else + { + mov->children[r] = NULL; + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur->children[r] = mov; + + mov->size = getChildrenSumSize(mov) + 1; + cur->size = getChildrenSumSize(cur) + 1; + } + + void lrotate3(TreeNode *cur) + { + const int l = 1; + const int r = 0; + // 1 right 0 left + TreeNode *mov = cur->children[l]; + + this->swap_node_kv(cur, mov); + + cur->children[r] = mov; + + cur->children[l] = mov->children[l]; + cur->children[l]->parent = cur; + + mov->children[l] = NULL; + + mov->size = 1; + } + + void lrotate(TreeNode *cur) + { + + const int l = 1; + const int r = 0; + // 1 right 0 left + TreeNode *mov = cur->children[l]; + + this->swap_node_kv(cur, mov); + + // mov->children[l]不可能为nil + mov->children[l]->parent = cur; + + cur->children[l] = mov->children[l]; + + // 解决mov节点孩子转移的问题 + if (mov->children[r] != NULL) + { + mov->children[l] = mov->children[r]; + } + else + { + mov->children[l] = NULL; + } + + if (cur->children[r] != NULL) + { + mov->children[r] = cur->children[r]; + mov->children[r]->parent = mov; + } + else + { + mov->children[r] = NULL; + } + + // 连接转移后的节点 由于mov只是与cur交换值,parent不变 + cur->children[r] = mov; + + mov->size = getChildrenSumSize(mov) + 1; + cur->size = getChildrenSumSize(cur) + 1; + } + + void fixSize(TreeNode *cur, ULONG ls, ULONG rs) + { + if (ls > rs) + { + tuple lllr = this->getChildrenSize(cur->children[0]); + ULONG llsize = std::get<0>(lllr); + ULONG lrsize = std::get<1>(lllr); + if (lrsize > llsize) + { + this->rlrotate(cur); + } + else + { + this->rrotate(cur); + } + } + else + { + tuple rlrr = this->getChildrenSize(cur->children[1]); + ULONG rlsize = std::get<0>(rlrr); + ULONG rrsize = std::get<1>(rlrr); + if (rlsize > rrsize) + { + this->lrrotate(cur); + } + else + { + this->lrotate(cur); + } + } + } + +public: + VBTree(Compare compare) + { + this->compare = compare; + this->root = NULL; + } + + TValue* get(TKey key) + { + for (TreeNode *n = this->root; n != NULL;) + { + int c = this->compare(key, n->key); + switch (c) + { + case -1: + n = n->children[0]; + break; + case 1: + n = n->children[1]; + break; + case 0: + return &n->value; + } + } + return NULL; + } + + void put(TKey key, TValue value) + { + + if (this->root == NULL) + { + TreeNode *node = new TreeNode(); + node->key = key; + node->value = value; + this->root = node; + return; + } + + std::vector vsize; + + for (TreeNode *cur = this->root;;) + { + if (cur->size > 8) + { + unsigned long factor = cur->size / 10; + unsigned long ls = cur->children[0]->size; + unsigned long rs = cur->children[1]->size; + if (rs >= ls * 2 + factor || ls >= rs * 2 + factor) + { + this->fixSize(cur, ls, rs); + } + } + + // cur->size++; + vsize.push_back(cur); + + int c = this->compare(key, cur->key); + if (c < 0) + { + if (cur->children[0] == NULL) + { + TreeNode *node = new TreeNode(); + node->key = key; + node->value = value; + + for (auto iter = vsize.begin(); iter != vsize.end();iter++) { + (*iter)->size ++ ; + } + + cur->children[0] = node; + node->parent = cur; + + if (cur->parent != NULL && cur->parent->size == 3) + { + if (cur->parent->children[0] == NULL) + { + this->lrrotate3(cur->parent); + } + else + { + this->rrotate3(cur->parent); + } + } + return; + } + cur = cur->children[0]; + } + else if (c > 0) + { + if (cur->children[1] == NULL) + { + TreeNode *node = new TreeNode(); + node->key = key; + node->value = value; + + for (auto iter = vsize.begin(); iter != vsize.end();iter++) { + (*iter)->size ++ ; + } + + cur->children[1] = node; + node->parent = cur; + + if (cur->parent != NULL && cur->parent->size == 3) + { + if (cur->parent->children[1] == NULL) + { + this->rlrotate3(cur->parent); + } + else + { + this->lrotate3(cur->parent); + } + } + return; + } + cur = cur->children[1]; + } + else + { + cur->key = key; + cur->value = value; + return; + } + } + }; + + /* data */ +}; diff --git a/src/vbtree.hpp b/src/vbtree.hpp deleted file mode 100644 index b4c0299..0000000 --- a/src/vbtree.hpp +++ /dev/null @@ -1,80 +0,0 @@ - - -#include -#include - -using namespace std; -using std::cout, std::endl; - -template -class VBTree -{ -public: - typedef struct Node - { - Node *children[2]; - Node *parent; - unsigned long size; - TKey key; - TValue value; - /* data */ - } ; - -public: - void put(TKey key, TValue value) { - Node *node = new Node(); - } - - // if tree.root == nil { - // tree.root = node - // return - // } - - // for cur := tree.root; ; { - - // if cur.size > 8 { - // factor := cur.size / 10 // or factor = 1 - // ls, rs := cur.children[0].size, cur.children[1].size - // if rs >= ls*2+factor || ls >= rs*2+factor { - // tree.fixSize(cur, ls, rs) - // } - // } - - // cur.size++ - - // c := tree.Compare(key, cur.key) - // if c < 0 { - // if cur.children[0] == nil { - // cur.children[0] = node - // node.parent = cur - - // if cur.parent != nil && cur.parent.size == 3 { - // if cur.parent.children[0] == nil { - // tree.lrrotate3(cur.parent) - // } else { - // tree.rrotate3(cur.parent) - // } - // } - // return - // } - // cur = cur.children[0] - // } else { - // if cur.children[1] == nil { - // cur.children[1] = node - // node.parent = cur - - // if cur.parent != nil && cur.parent.size == 3 { - // if cur.parent.children[1] == nil { - // tree.rlrotate3(cur.parent) - // } else { - // tree.lrotate3(cur.parent) - // } - // } - // return - // } - // cur = cur.children[1] - // } - // } - - /* data */ -};