If you only use RotateLeft/RotateRight to move the nodes around you'll end up with a tree with linear hieght because all nodes to the left will hang off left childs, and all nodes to the right hang off right childs. Basically you degrade into a doubly linked list. To avoid this whenever we detect that we'd do two RotateLeft (or Right) operations in a row we in fold the tree over such that the depth of the opposing child is only pushed down one rather than down two. If you consider the worst case tree (no internal nodes) as the input you can see that the result will contain internal nodes. This operation is what (over time) balances the tree to logarithmic height. static private ImTree<TK, TV> SkipLeft(ImTree<TK, TV> root){// O LL// / \ / \// L r lll O// / \ ---> / \// LL lr L r// / \ / \ // lll llr llr lrreturn new ImTree<TK, TV>(root.l_.l_.k_, root.l_.l_.v_,root.l_.l_.l_,new ImTree<TK, TV>(root.k_, root.v_,new ImTree<TK, TV>(root.l_.k_, root.l_.v_,root.l_.l_.r_,root.l_.r_),root.r_));}static private ImTree<TK, TV> SkipRight(ImTree<TK, TV> root){// O RR// / \ / \// l R O rrr// / \ ---> / \ // rl RR l R // / \ / \ // rrl rrr rl rrlreturn new ImTree<TK, TV>(root.r_.r_.k_, root.r_.r_.v_,new ImTree<TK, TV>(root.k_, root.v_,root.l_,new ImTree<TK, TV>(root.r_.k_, root.r_.v_,root.r_.l_,root.r_.r_.l_)),root.r_.r_.r_);} |