基數排序的C++實現(解析)

來源:互聯網
上載者:User

基數排序(Radix sort)是一種非比較型整數排序演算法,其原理是將整數按位元切割成不同的數字,然後按每個位元分別比較。由於整數也可以表達字串(比如名字或日期)和特定格式的浮點數,所以基數排序也不是只能使用於整數。基數排序的發明可以追溯到1887年赫爾曼·何樂禮在打孔卡片製表機(Tabulation Machine)上的貢獻。時間複雜度是 O(k·n),其中n是排序元素個數,k是數字位元。——來自維基百科
空間複雜度為O(B),其中B為基數Base,如10或16等,不是一個穩定排序。
維基百科上有C++實現的代碼,夠簡練,看了一段時間才看明白,在每次基於各個數位上的數字散列和合并的時候,用的方式夠巧妙,是我沒想出來的!特在此處貼出來,然後解釋之~

我仿著維基百科給的C++代碼,實現如下:

#include <iostream>#include <cstring>#include <ctime>using namespace std;struct Num{int v;Num *next;Num(){next=0;}};void sort(int *arr,int len){const int RADIX=10;//以10為基進行排序int tmp;Num *topBox[RADIX];//桶中最新添加進去的元素Num *bottomBox[RADIX];//桶底元素for(int i=0;i<RADIX;++i){topBox[i]=bottomBox[i]=new Num;}//找最大值tmp=arr[0];for(int i=0;i<len;++i){if(tmp<arr[i])tmp=arr[i];}//計算最大值有多少個數位int digCnt=1;tmp/=RADIX;while(tmp){++digCnt;tmp/=RADIX;}//將數群組轉換成鏈表Num *head=new Num;Num *cur;cur=head;for(int i=0;i<len;++i){cur->next=new Num;cur->next->v=arr[i];cur=cur->next;}//開始基數排序int factor=1;for(int i=0;i<digCnt;++i){//散列for(cur=head->next;cur;cur=cur->next){tmp=(cur->v/factor)%RADIX;topBox[tmp]->next=cur;topBox[tmp]=topBox[tmp]->next;}//合并cur=head;for(int j=0;j<RADIX;++j){if(topBox[j]!=bottomBox[j]){cur->next=bottomBox[j]->next;cur=topBox[j];topBox[j]=bottomBox[j];}}//必須將最後一個數位next賦值為NULL,否則導致鏈表形成環,導致再次"散列"時會死迴圈cur->next=0;//擴大因子,用於取下一個數字factor*=RADIX;}//使用鏈表給數組賦值cur=head->next;for(int i=0;i<len;++i,cur=cur->next){arr[i]=cur->v;}}void test(){int len=20;int *heap=new int[len];srand(time(0));for(int i=0;i<len;++i){heap[i]=rand()%10000;}cout<<"初始數組:"<<endl;printArray(heap,len);//mySort(heap,0,len-1);sort(heap,len);printArray(heap,len);delete heap;}

bottomBox數組不會變化,因為它儲存的是每個“桶”的初始元素,而topBox數組一直在變化,因為它始終指向“桶”中最近被添加的數字,這是由"基數排序中的每個"桶"必須在鏈表尾部添加新的數字"決定的,鏈表的尾部,就是topBox(可以把這個"桶"想象成一個開口向下的倒著的桶~)。起始狀態,bottomBox與topBox裡的每個元素都是一樣的,因為每個"桶"裡都沒有數字,隨著散列的進行,有些"桶"裡就被先後放入多個數字,此時topBox隨之變化,使自己總是指向"桶"最頂部的數字,也就是最新被添加的那個數字。

散列完成之後,需要將本次的散列結果按“在數組中散列到的桶號”串聯起來,用於下次散列,串聯的時候,每個“桶”中,開始的元素由bottomBox儲存,終止元素由topBox儲存,而且,如果該“桶”是空的,那麼bottomBox對應的值與topBox對應的值相等,反過來說:凡是bottomBox中與topBox對應值不相等的那個“桶”裡肯定有數字串,這個串的起始數字由bottomBox儲存,終止數字由topBox儲存。很巧妙吧!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.