static SetNode* rotate_double (SetNode *root, int dir) { root->link[!dir] = rotate_single(root->link[!dir], !dir); return rotate_single(root, dir); }
void rotate(vector<vector<int>>& matrix) { for (int i=0; i<matrix.size()/2; i++){ rotate_single(matrix, i); } }
static void rebalance(Ttree *ttree, TtreeNode **node, TtreeCursor *cursor) { int lh = left_heavy(*node); int sum = abs((*node)->bfc + (*node)->sides[opposite_side(lh)]->bfc); if (sum >= 2) { rotate_single(node, opposite_side(lh)); goto out; } rotate_double(node, opposite_side(lh)); /* * T-tree rotation rules difference from AVL rules in only one aspect. * After double rotation is done and a leaf became a new root node of * subtree and both its left and right childs are half-leafs. * If the new root node contains only one item, N - 1 items should * be moved into it from one of its childs. * (N is a number of items in selected child node). */ if ((tnode_num_keys(*node) == 1) && is_half_leaf((*node)->left) && is_half_leaf((*node)->right)) { TtreeNode *n; int offs, nkeys; /* * If right child contains more items than left, they will be moved * from the right child. Otherwise from the left one. */ if (tnode_num_keys((*node)->right) >= tnode_num_keys((*node)->left)) { /* * Right child was selected. So first N - 1 items will be copied * and inserted after parent's first item. */ n = (*node)->right; nkeys = tnode_num_keys(n); (*node)->keys[0] = (*node)->keys[(*node)->min_idx]; offs = 1; (*node)->min_idx = 0; (*node)->max_idx = nkeys - 1; if (!cursor) { goto no_cursor; } else if (cursor->tnode == n) { if (cursor->idx < n->max_idx) { cursor->tnode = *node; cursor->idx = (*node)->min_idx + (cursor->idx - n->min_idx + 1); } else { cursor->idx = first_tnode_idx(ttree); } } } else { /* * Left child was selected. So its N - 1 items * (starting after the min one) * will be copied and inserted before parent's single item. */ n = (*node)->left; nkeys = tnode_num_keys(n); (*node)->keys[ttree->keys_per_tnode - 1] = (*node)->keys[(*node)->min_idx]; (*node)->min_idx = offs = ttree->keys_per_tnode - nkeys; (*node)->max_idx = ttree->keys_per_tnode - 1; if (!cursor) { goto no_cursor; } else if (cursor->tnode == n) { if (cursor->idx > n->min_idx) { cursor->tnode = *node; cursor->idx = (*node)->min_idx + (cursor->idx - n->min_idx); } else { cursor->idx = first_tnode_idx(ttree); } } n->max_idx = n->min_idx++; } no_cursor: memcpy((*node)->keys + offs, n->keys + n->min_idx, sizeof(void *) * (nkeys - 1)); n->keys[first_tnode_idx(ttree)] = n->keys[n->max_idx]; n->min_idx = n->max_idx = first_tnode_idx(ttree); } out: if (ttree->root->parent) { ttree->root = *node; } }