淺談splay的雙旋


昨晚終於明白了splay雙旋中的一些細節,今日整理如下

注:題目用的2002HNOI營業額統計,測試結果均來及codevs 網站的評測結果 http://codevs.cn/problem/1296/

本題完整代碼請見http://www.cnblogs.com/TheRoadToTheGold/p/6372009.html

1、這是旋轉部分的代碼

inline void splay(int x,int goal)
        {            
            while(pre[x]!=goal)
            {
                int y=pre[x];
                int kind=ch[y][0]==x;
                if(pre[y]==goal) rot(x,kind);//父節點是目標節點,單旋
                else
                {
                    kind=ch[pre[y]][0]==y;
                    if(ch[y][!kind]==x)//一字型
                    {                        
                        rot(y,kind);
                        rot(x,kind);
                    }
                    else//之字型
                    {
                        rot(x,!kind);
                        rot(x,kind);
                    }
                }
            }
            root=x;
        }

理解較淺,目前認為之字形旋轉的本質就是單旋,一字型才算雙旋

2、雙旋與單旋的區別

先看看運行結果

左邊是單旋,右邊是雙旋,空間幾乎一樣,時間差距很大

why?    

 圖1:

圖2的單旋結果

         

 圖2:

雙旋結果                                                                                                                        

           

可以發現,雙旋之后的層數要比單旋之后的層數少1

這只是5層(本圖中第6層對5不干擾),如果層數更多呢

所以,雙旋層數比單旋要更少

手推一下,上圖中第1次旋轉結果的樹的形態與單旋結果的樹的形態是一樣的,只是4和3換了個位

所以雙旋的優越性在一字型層數>4時才會體現

為什么雙旋層數要少?

繼續觀察圖2的第2個和第3個,發現少的那一層是因為4和1處在了同一層

即雙旋 使 待旋轉點的旋轉方向的孩子 與待旋轉點的爺爺節點  處在同一層

換用字母表示:

設a的旋轉方向的孩子是b,a的父節點是c,c的父節點是d

那么雙旋使b、d處在同一層,因為b、d都成為了c的孩子

為什么?分析雙旋的兩次旋轉

先旋轉父節點,使爺爺節點和自己都成為父節點的孩子,此時父節點和自己處在同一層,原來的爺爺節點成為自己的父節點

然后旋轉自己,自己旋轉方向的孩子節點成為自己現在父節點(原先爺爺節點)的孩子,也就是和自己原先父節點處在了同一層

這也是我認為之字型旋轉也是單旋的原因,因為之字型旋轉是讓自己旋轉2次,與單旋並無不同

3、旋轉順序

A、代碼中一字型旋轉順序是先轉父節點,再轉自己

①不能改成先轉自己,再轉父節點

先轉自己讓自己到父節點的位置,父節點到自己的孩子位置,再轉父節點,又轉回去了,跟沒轉一個樣

②可以改成旋轉自己兩次,但那樣就相當於單旋

B、之字型旋轉的旋轉順序是連續轉自己2次

看圖,

可以發現連續轉自己兩次,每次使自己上移一層

而如果先轉父節點,可以發現自己原來在哪兒還在那兒,只是父節點和爺爺節點換了而已,相當於這一次白轉了

當然你也可以先轉父節點,再轉自己(兩次旋轉方向相同),因為的正確性是有保證的

對比一下,上邊是先轉父節點,再轉自己,下邊是連續轉自己兩次(一字型旋轉均是先轉父節點,再轉自己)

上邊空間明顯大,時間也多點兒

         


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM