一個線性時間下的原地置換排序演算法

來源:互聯網
上載者:User

著作權,轉載請註明出處,謝謝!

一個線性時間下的原地置換排序演算法

排序演算法

現有的線性時間排序(時間複雜度為ο(n)演算法,比如計數排序,基數排序,桶排序等,雖然在時間複雜度上都能保持線性,但不能進行原地置換排序,需要額外的輔助空間.一個演算法能否同時做到時間複雜度為ο(n),空間複雜度為Ω(1)呢?

我們知道,在現有的常規線性演算法(計數排序,桶排序,基數排序等)當中,計數排序和桶排序因為不是原地置換排序,因此都需要額外的輔助空間來完成排序,因此無法達到上述目的,而基數演算法本身是一個複合演算法,如果能保證其位排序的演算法能做到空間複雜度為Ω(1)和時間複雜度ο(n),那顯然可以達到上述要求的演算法目標.對於基數排序中的位排序要求必須具有穩定性.既要滿足線性時間,常量空間,並且穩定的演算法,在現有常用演算法中還沒有這種演算法可以達到這種要求。

我們選基數排序作為實現這個演算法目標的基本演算法,由於我們進行的是整數排序,基數排序的位就是整數二進位表示裡的位,而對於整數的二進位形式,每位上的數就只有0和1(這是個很有利的因素),而對0和1序列排序做到線性時間,只需要利用0作為基元,做一次快排劃分即可,快排劃分的演算法時間複雜度是ο(n),而且也是原地置換排序,空間上的要求可以滿足(Ω(1)),但問題在於對於基數排序,要求其位排序必須是穩定排序,而快排劃分顯然不是穩定的。但如果我們能找到一種方法將這種不穩定帶來的影響消除,使得其不影響最終結果,問題就解決了。那麼而怎樣讓快排劃分不影響最終結果呢?

我們知道基數排序有兩種基本的形式,一種是從低位到高位進行排序,一種是從高位到低位進行,經過分析發現,如果採用從高位到低位的方式進行,是可以讓快排劃分不影響到最終結果的,我們考慮一般情況,設B(k),B(k-1)….,B(1)表示一個基數排序所有的位(對於32位整數k=32),對第i位進行排序,而前m位(m=k-i-1)位已經排好序B(k)…B(i+1),在進行i位排序時,如果我們的快排劃分只針對前m位相同的情況進行,則快排劃分的結果顯然不會影響最終結果.這樣對於第i位上的一次快排,就可以轉換成若干個小區間的快排劃分(用前m位元進行劃分,前m位相同的為一個區間),而且由於前m位已經排好序,那麼顯然前m位相同的都必然緊挨在一起,這種情況下雖然一次快排劃分變成了p次快排劃分(p<n),但整體上的時間複雜度並沒有增加,雖然在具體的演算法技巧處理時會考慮索引回溯,但時間複雜度不會改變,因為最極端的回溯小於等於n,因此時間複雜度最多為2n.而對於整數而言,前m位的擷取和比較都非常快,所以在進行時間複雜度分析時可以不考慮,所以整體上演算法每位上排序時間複雜度還是為32n到64n之間,而回溯通過一定技巧處理也可以消除,那麼演算法的時間複雜度就可以小於32n.由於這種位演算法空間複雜度為Ω(1),因此整個演算法滿足前面提到的演算法目標。

下面是具體的C#語言下的演算法實現(為了減少交換次數,這裡位排序不是嚴格按照快排劃分進行,而是針對0和1的特點,用一個指標i指向序列第1個1,遍曆指標在前,遇到0就與i交換,i隨後右移一位,這可以大大減少交換次數):

       private void BitSortAndDelRepeatorsA(int[] A)

       {

           //擷取數組長度

           int theN = A.Length;

           //從高位到低位開始排序,這裡從31位開始,32位是符號位不考慮,

           //或者單獨考慮。

           for (int i = 31; i >= 1; i--)

           {

                //當前排序之前的值,只有該值相同才進行快排分組,如果不相同,

//則重新開始另外一次快排

                //這很關鍵,否則快排的不穩定就會影響最後結果.

                int thePrvCB = A[0] >>(i)  ;

                //快排開始位置,會變化

                int theS = 0;

                //快排插入點

                int theI = theS-1;

                //2進位基數,用於測試某一位是否為0

                int theBase = 1 << (i-1);

                //位基元始終為0,

                int theAxBit = 0;

              

                //分段快排,但總體上時間複雜度與快排分組一樣.

                for (int j = 0; j < theN; j++)

                {

 

                    //擷取當前數組值的前面已拍過序的位元值。

                    int theTmpPrvCB = A[j]>> (i);

                    //如果前面已排過的位不相同,則重新開始一次快排.

                    if (theTmpPrvCB !=thePrvCB)

                    {

                        theS = j;

                        theI = theS - 1;

                        theAxBit = 0;

                        thePrvCB = theTmpPrvCB;

                        j--;//重新開始排,回朔一位.

                        continue;

                    }

                    //如果前面的數相同,則尋找第1個1,thI指向其

                    //如果相同,則按快排處理

                    int theAJ = (A[j] &(theBase)) > 0 ? 1 : 0;

                    //如果是重新開始排,則尋找第1個1,並人theI指向其.這可以

//減少交換,加快速度.

                    if (theI < theS)

                    {

                       if (theAJ == 0)

                        {

                            continue;

                        }

                        theI = j;//Continue保證J從theI+1開始.

                        continue;

                    }

                    //交換.

                    if (theAJ <= theAxBit)

                    {

                        int theTmp = A[j];

                        A[j] = A[theI];

                        A[theI] = theTmp;

                        theI++;

                    }

               }

           }

       }

演算法分析

時間複雜度雖然有32*n,但由於32是個常數,因此整個演算法的時間複雜度還是ο(n),空間複雜度方面,演算法中只是利用了有限的幾個交換變數(<20),因此空間複雜度為Ω(1)。但演算法的穩定性方面,由於其位演算法是不穩定的,因此整個演算法也是不穩定的。

該演算法經過我大量測試,其複雜度符合演算法分析結果。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.