Home Manual Reference Source

src/deletion/delete_case5.js

import assert from 'assert';
import BLACK from '../color/BLACK.js';
import RED from '../color/RED.js';
import Node from '../types/Node.js';
import rotate_left from '../rotate/rotate_left.js';
import rotate_right from '../rotate/rotate_right.js';
import sibling from '../family/sibling.js';

/**
 * Preconditions:
 *   - n is black
 *   - all root-leaf paths going through n have a black height of b - 1
 *   - all other root-leaf paths have a black height of b
 *   - n is not the root
 *   - n's sibling is black
 *   - if n is a left child, the right child of n's sibling is red
 *   - if n is a right child, the left child of n's sibling is red
 *
 * @param {Node} n - The input node.
 * @return {Node} The root of the modified subtree.
 */
const delete_case5 = (n) => {
	assert(n instanceof Node);
	assert(n._color === BLACK);
	assert(n.parent !== null);
	const s = sibling(n);
	assert(s instanceof Node);
	assert(s._color === BLACK);

	/**
	 * Increment the black height of all root-leaf paths going through n by
	 * swapping the colors of n's parent and n's sibling and
	 * rotating at n's parent. This decrements the black height of all
	 * root-leaf paths going through n's sibling's right child.
	 * We can repaint n's sibling's right child in black to fix this.
	 * We are done.
	 *
	 *           ?                          ?
	 *        /     \                     /   \
	 *      >B        B                 B       B
	 *      / \      / \               / \     / \
	 *     -   -   =     R     -->   >B   =   =   B
	 *                  / \          / \         / \
	 *                 =   B        -   -       -   -
	 *                    / \
	 *                   -   -
	 */

	// Swap the color of the parent and the sibling.
	s._color = n.parent._color;
	n.parent._color = BLACK;

	if (n === n.parent.left) {
		assert(s.right._color === RED);
		s.right._color = BLACK;
		rotate_left(n.parent);
		return s;
	}

	// Symmetric case

	assert(s.left._color === RED);
	s.left._color = BLACK;
	rotate_right(n.parent);
	return s;
};

export default delete_case5;