平衡树(一)伸展BST

思想:

通过执行两次旋转操作,把节点从作为根的孙子节点之一的位置带到树的顶部。

首先,执行一次旋转,将该节点成为根的一个孩子节点。

接着,执行另一次旋转,使它成为根。

根据从根到插入节点的两个链接是否已相同方式定向,存在4种不同的情况:

左--左:从根处右旋转两次。

左--右:在左孩子进行左旋转,然后在根进行右旋转。

右--右:在根处左旋转两次。

右--左:在右孩子进行右旋转,然后在根进行左旋转。


程序:

void STinsert(Item item)
{
    head = splay(head,item);
}

link splay(link h,Item item)
{
    Key v = key(item);
    if(h == z)
        return NEW(item,z,z,l);

    if(less(v,key(h->item)))//左
    {

        if(hl == z)
            return NEW(item,z,h,h->N+1);

        if(less(v,key(hl->item)))//左--左
        {
            hll = splay(hll,item);
            h = rotR(h);
        }
        else                     //左--右
		{
			hlr = splay(hlr,item); 
			hl = rotL(hl); 
		} 
			return rotR(h); 
	} 
	else //右 
	{
		if(hr ==z)
			return NEW(item,h,z,h->N+1); 
		if(less(key(hr->item),v))//右--右 
		{
			hrr = splay(hrr,item);
			h = rotL(h); 
		} 
		else             //右--左 
		{ 
			hrl = splay(hrl,item);
			hr = rotR(hr);
		} 
			return rotL(h); 
	}
 }
 
 

当我们使用伸展插入法向BST中插入一个节点时,我们不仅要把那个节点带到根处,而且要把我们在搜索路径上遇到的其他节点带到根附近。准确的说,我们所进行的旋转将从根到任何我们遇到的节点的距离降低了一半。


猜你喜欢

转载自blog.csdn.net/u010034085/article/details/80684637