排序算法-基數排序

說明

     在之前所介紹過的排序方法,都是屬於「比較性」的排序法,也就是每次排序時,都是比較整個鍵值的大小以進行排序。這裏所要介紹的「基數排序法」(radix sort)則是屬於「分配式排序」(distribution sort), 基數排序法又稱「桶子法」(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些「桶」中,藉以達到排序的作用,基數排序法是屬於穩定性的排序,其時間複雜度爲O (nlog(r)m),其中r爲所採取的基數,而m爲堆數,在某些時候,基數排序法的效率高於其它的比較性排序法。
解法

     基數排序的方式可以採用LSD(Least sgnificant digital)或MSD(Most sgnificant digital),LSD的排序方式由鍵值的最右邊開始,而MSD則相反,由鍵值的最左邊開始。以LSD爲例,假設原來有一串數值如下所示:

73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根據個位數的數值,在走訪數值時將它們分配至編號0到9的桶子中:

0       1        2        3       4       5       6       7       8       9


         81                                 65                                 39

                            43     14     55                       28

                            93    

                   22     73

接下來將這些桶子中的數值重新串接起來,成爲以下的數列:

81, 22, 73, 93, 43, 14, 55, 65, 28, 39

接着再進行一次分配,這次是根據十位數來分配:

0       1       2       3       4       5       6       7       8       9


                  28     39

         14     22              43     55     65     73     81     93

接下來將這些桶子中的數值重新串接起來,成爲以下的數列:

14, 22, 28, 39, 43, 55, 65, 73, 81, 93
這時候整個數列已經排序完畢;如果排序的對象有三位數以上,則持續進行以上的動作直至最高位數爲止。
LSD的基數排序適用於位數小的數列,如果位數多的話,使用MSD的效率會比較好,MSD的方式恰與LSD相反,是由高位數爲基底開始進行分配,其他的演算方式則都相同。

代碼:

void basesort(int number[],int maxbitnum)//maxbitnum最大數值的位數
{
	int temp[10][10] = {0};
	int order[10] = {0};
	int i,j,k,n,lsd;

	int highbitnumber = 1; //最高位對應的權值,1、10、100、...
	while(maxbitnum-- > 1)
		highbitnumber *= 10;

	k = 0;
	n = 1;
	while(n <= highbitnumber) 
	{
		for(i=0;i<MAX;++i)
		{
			lsd = ((number[i]/n)%10);
			temp[lsd][order[lsd]] = number[i];
			++order[lsd];
		}
		printf("重新排列: ");
		for(i=0;i<MAX;++i)
		{
			if(order[i] != 0)
			{
				for(j=0;j<order[i];++j)
				{
					number[k] = temp[i][j];
					printf("%d ",number[k]);
					++k;
				}
				order[i] = 0;
			}
		}
		printf("\n");
		n *= 10;
		k = 0;
	}
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章