/** * This does a single "left" rotation on a given node 'a'. The rotated * node is returned. * * @private * @param a the node to rotate. * @return the rotated node */ static PropPtr rotate_left_single(PropPtr a) { PropPtr b = a->right; a->right = b->left; b->left = a; fixup_height(a); fixup_height(b); return b; }
static PropPtr rotate_right_single(PropPtr a) { PropPtr b = AVL_LF(a); AVL_LF(a) = AVL_RT(b); AVL_RT(b) = a; fixup_height(a); fixup_height(b); return (b); }
/** * This call balances the AVL node 'a' and returns the balanced node. * * @private * @param a the node to balance * @return the balanced node */ static PropPtr balance_node(PropPtr a) { int dh = height_diff(a); if (abs(dh) < 2) { fixup_height(a); } else { /* One might argue the brackets are not necessary here, but * this looked like a train wreck without them :) */ if (dh == 2) { if (height_diff(a->right) >= 0) { a = rotate_left_single(a); } else { a = rotate_left_double(a); } } else if (height_diff(a->left) <= 0) { a = rotate_right_single(a); } else { a = rotate_right_double(a); } } return a; }
/** * This does a double "right" rotation on a given node 'a'. The rotated * node is returned. * * @private * @param a the node to rotate. * @return the rotated node */ static PropPtr rotate_right_double(PropPtr a) { PropPtr b = a->left, c = b->right; a->left = c->right; b->right = c->left; c->right = a; c->left = b; fixup_height(a); fixup_height(b); fixup_height(c); return c; }
static PropPtr rotate_left_double(PropPtr a) { PropPtr b = AVL_RT(a), c = AVL_LF(b); AVL_RT(a) = AVL_LF(c); AVL_LF(b) = AVL_RT(c); AVL_LF(c) = a; AVL_RT(c) = b; fixup_height(a); fixup_height(b); fixup_height(c); return c; }
static PropPtr balance_node(PropPtr a) { int dh = height_diff(a); if (abs(dh) < 2) { fixup_height(a); } else { if (dh == 2) if (height_diff(AVL_RT(a)) >= 0) a = rotate_left_single(a); else a = rotate_left_double(a); else if (height_diff(AVL_LF(a)) <= 0) a = rotate_right_single(a); else a = rotate_right_double(a); } return a; }