旋转:保持二叉查找树性质的查找树局部操做。code
左旋:blog
void leftRotate(NODE *x) { NODE *y = x->r; x->r = y->l; if (y->l != nil) { y->l->p = x; } y->p = x->p; if (x->p == nil) { root = y; } else { if (x == x->p->l) { x->p->l = y; } else { x->p->r = y; } } y->l = x; x->p = y; }
右旋:ip
void rightRotate(NODE *x) { NODE *y = x->l; x->l = y->r; if (y->r != nil) { y->r->p = x; } y->p = x->p; if (x->p == nil) { root = y; } else { if (x == x->p->l) { x->p->l = y; } else { x->p->r = y; } } y->r = x; x->p = y; }
13.2-1 写出RIGHT-ROTATE的伪代码。class
见笔记。file
13.2-2 证实:在一棵有n个结点的二叉查找树中,恰好有n-1种可能的旋转。二叉树
除根结点外,每一个结点都能有父结点作旋转。im
n=1时,只有根结点,0种可能的旋转。img
假设n=k-1时,有k-2种旋转。co
当n=k时,添加了一个结点,则此结点为叶子结点,该结点可与其父亲旋转。恰好有k-1种可能的旋转。void
所以有n个结点的二叉查找树恰好有n-1种可能的旋转。
13.2-3 设在图中左边一棵树中,a,b和c分别为子树α,β和γ中的任意结点。若是将结点x左旋,则a,b和c的深度会如何变化?
a-=1 b+=1 c+=1
13.2-4 证实:任何一棵含n个结点的二叉查找树,能够经过O(n)次旋转,转变为另外一棵含n个结点的二叉查找树。
能够经过右旋全部有左孩子的节点将一颗二叉树变成一个单链的仅有右孩子的二叉树。
也能够经过这个过程的反向操做将一个单链的二叉树变成任意形态的二叉树。
*13.2-5 若是可以使用一系列的RIGHT-ROTATE调用来把一个二叉查找树T1变为二叉查找树T2,则说T1能够右转成T2。请给出一棵两棵树的例子,其中T1不能右转成T2。而后证实若是T1能够右转成T2,则它能够使用O(n^2)次RIGHT-ROTATE调用来右转。