桶排序(bucket sort)從一個一維的待排序的正整數數組和一個二維整數數組開始,其中二維數組的行下標是從0到9,列下標是從0到n-1,n是一維數組中待排序值的個數。這個二維數組的每一行都成為一個桶。編寫一個函數bucketSort,它採用一個整數數組和該數組的大小作為參數,並執行以下操作:
a)對於一維數組的每個值,根據值的個位元,將其放到桶數組的各行中。例如,97放在第7行,3放在第3行,100放在第0行。這稱為“分布過程”。
b)在桶數組中逐行迴圈便利,並把值複製回原始數組。這稱為“收集過程”。上述值在一維數組中的新次序是 100、3和97.
c)對隨後的每個數位(十位、百位、千位等)重複這個過程。在第二遍排序時,100放在第0行,3放在第0行(因為3沒有十位),97放在第9行。收集過程之後,一維數組 中值的順序為100、3和97.在第三遍排序時,100放在第一行,3放在第0行,97放在第0行(在3之後)。在最 後一次收集過程後,原屬數組就是有序的了。
請注意,二維桶數組的大小是被排序的整數數組大小的10倍。這種排序方法的效能比插入排序好,但是需要非常多的記憶體空間。插入排序只需要額外的一個資料元素的空間。這使一個時間權衡的範例:桶排序使用的記憶體空間比插入排序多,但是效能比較好。這個版本的桶排序需要在每一遍排序時把所有資料複製回原始數組。另外一種方法是建立第二個二維桶數組,並在這兩個桶數組間重複交換資料。
Input
第一行1個整數t,表示有t組資料。每組資料有兩行:第1行為一個整數n(n不大於100),表示數組有n個元素;第2行有n個以空格隔開的整數,即數組中每個元素的值。
Output
共t行,每行n個以空格隔開的整數,即每個數組的元素排序後的序列。
Sample Input
1
3
3 1 2
Sample Output
1 2 3
#include<iostream>
#include<cstdlib>
using namespace std;
//求待排序數種最大的數的位元
int getLargest(int a[], int n){
int i,max,temp;
for(i=1,max=0; i<n; i++)
if(a[i]>a[max]) max=i;
i=0;
temp=a[max];
while(temp!=0){
temp/=10;
i++;
}
return i;
}
//求一個數第i位的數字(從低到高)
int getBitNum(int num,int i){
while(--i){
num/=10;
}
return num%10;
}
//桶排序主程式
void BucketSort(int a[], int n) {
int i, j, max, **bucket=new int*[10]; // i,j用來控制分布元素。
int b[10]={0},k,l,bit; //數組b[10]用來記錄每個桶內元素個數
//k,l用來控制元素回收過程
max=getLargest(a,n);
for(i=0; i<10; i++)
bucket[i]=new int[n];
for(i=0; i<max; i++){
for(j=0; j<n; j++){
bit=getBitNum(a[j],i+1);
bucket[bit][b[bit]]=a[j];
b[bit]++;
}
j=0;
for(k=0;k<10;k++)
for(l=0; l<b[k]; l++){
a[j++]=bucket[k][l];
}
for(j=0; j<10; j++)
b[j]=0;
}
}
int main () {
int t,n,*p,i;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
p=new int[n];
for(i=0; i<n; i++)
scanf("%d",&p[i]);
BucketSort(p,n);
for(i=0; i<n; i++)
printf("%d ",p[i]);
putchar('/n');
}
return 0;
}
寫完後拿到PKU1002試了一下,結果比C內建的qsort還慢,開始沒明白過來。後來仔細想想可能是外排序2維數組的構造用的是動態分配。動態分配儲存空間的時候可能耗費了太多的時間,所以改用靜態2數組來儲存。程式如下:
#include<iostream>
#include<cstdlib>
using namespace std;
#define MaxNum 100
int bucket[10][MaxNum];
//求待排序數種最大的數的位元
int getLargest(int a[], int n){
int i,max,temp;
for(i=1,max=0; i<n; i++)
if(a[i]>a[max]) max=i;
i=0;
temp=a[max];
while(temp!=0){
temp/=10;
i++;
}
return i;
}
//求一個數第i位的數字(從低到高)
int getBitNum(int num,int i){
while(--i){
num/=10;
}
return num%10;
}
//桶排序主程式
void BucketSort(int a[], int n) {
int i, j, max; // i,j用來控制的分布過程
int b[10]={0},k,l,bit; //數組b[10]用來記錄每個桶內元素個數
//k,l用來控制元素回收過程
max=getLargest(a,n);
for(i=0; i<max; i++){
for(j=0; j<n; j++){
bit=getBitNum(a[j],i+1);
bucket[bit][b[bit]]=a[j];
b[bit]++;
}
j=0;
for(k=0;k<10;k++)
for(l=0; l<b[k]; l++){
a[j++]=bucket[k][l];
}
for(j=0; j<10; j++)
b[j]=0;
}
}
int main () {
int t,n,*p,i;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
p=new int[n];
for(i=0; i<n; i++)
scanf("%d",&p[i]);
BucketSort(p,n);
for(i=0; i<n; i++)
printf("%d ",p[i]);
putchar('/n');
}
return 0;
}
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/tctony/archive/2007/11/22/1898240.aspx