思想:
通过执行两次旋转操作,把节点从作为根的孙子节点之一的位置带到树的顶部。
首先,执行一次旋转,将该节点成为根的一个孩子节点。
接着,执行另一次旋转,使它成为根。
根据从根到插入节点的两个链接是否已相同方式定向,存在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中插入一个节点时,我们不仅要把那个节点带到根处,而且要把我们在搜索路径上遇到的其他节点带到根附近。准确的说,我们所进行的旋转将从根到任何我们遇到的节点的距离降低了一半。