2011-08-01 17:26:20Morris

[分析] ZJ 排序大車拼

由於 2011/8/1 看到討論區, 砲轟連連, 有感而發

ZJ 上面充斥著排序題, 我就懶得再多做說明了,
看到排序題, 我自己都煩了, 不過效率大家總是認為O(nlogn)最快, 現在來做一下分析,
先限定數字個數小於 1000萬, 每個數字介於 0 ~ 2147483647

1. Std::sort 內建排序, 這應該不用多做說明
2. Radix sort 基數排序 O(8n)
3. Merge sort 合併排序 O(nlogn)
4. Sleep sort ...
5. Splay tree 伸展樹
6. AVL   tree 平衡樹
7. Heap  sort 堆積排序
   (下面的速度全部沒有包括輸出, 但是 heap sort 輸出也要 nlogn, 因此下面的消耗時間要 *2)
8. bin+insert 分堆的插入排序,
   下面程式碼是將 2147483647 分成 10萬堆, 也就是 [0,21474]做一組

(1) n = 10,0000

排序類別       消耗時間

Std::sort    0.036000s
Radix sort   0.026000s
Merge sort   0.041000s
Sleep sort   100000s
Splay tree   0.095000s
AVL   tree   0.111000s
Heap  sort   0.026000s
bin+insert   0.001000s

(2) n = 100,0000

排序類別       消耗時間

Std::sort    0.378000s
Radix sort   0.258000s
Merge sort   0.434000s
Sleep sort   1000000s
Splay tree   1.449000s
AVL   tree   1.826000s
Heap  sort   0.256000s
bin+insert   0.445000s


(3) n = 250,0000

排序類別       消耗時間

Std::sort    0.980000s
Radix sort   0.625000s
Merge sort   1.140000s
Sleep sort   2500000s
Splay tree   4.178000s
AVL   tree   5.371000s
Heap  sort   0.647000s
bin+insert   1.865000s

(4) n = 500,0000

排序類別       消耗時間

Std::sort    1.967000s
Radix sort   1.291000s
Merge sort   2.270000s
Sleep sort   5000000s
Splay tree   9.392000s
AVL   tree   11.813000s
Heap  sort   1.291000s
bin+insert   6.179000s

(5) n = 1000,0000

排序類別       消耗時間

Std::sort    4.000000s
Radix sort   2.591000s
Merge sort   4.655000s
Sleep sort   10000000s
Splay tree   21.581000s
AVL   tree   26.241000s
Heap  sort   2.597000s
bin+insert   23.127000s


測試程式碼 :
1. Std::sort
#include<iostream>
int T,n,t[10000000],i,l,top=0,r;
bool q=0;
main()
{
    freopen("in1.txt", "rt", stdin);  
    freopen("out2.txt", "w+t", stdout);
    clock_t st, ed;
    st = clock();
    while(scanf("%d", &t[top]) == 1) top++;
    /*for(i=0;i<l;i++)
    {
        if(a[i]>='0'&&a[i]<='9')
        r=r*10+a[i]-'0',q=1;
        else if(q)t[top++]=r,r=0,q=0;
    }
    if(q)t[top++]=r;*/
    std::sort(t,t+top);
    /*for(i=0;i<top;i++)printf("%d ",t[i]);*/
    ed = clock();
    printf("%f\n", (float)(ed - st )/CLOCKS_PER_SEC);
}

2.Radix sort
#include<stdio.h>
#include<time.h>
#define    MaxN 10000001
void RadixSort(int *A, int *B, int n) {
    int a, x, d, *T, C[256];
    for(x = 0; x < 4; x++) {
        d = x*8;
        for(a = 0; a < 256; a++)        C[a] = 0;
        for(a = 0; a < n; a++)        C[(A[a]>>d)&255]++;
        for(a = 1; a < 256; a++)    C[a] += C[a-1];
        for(a = n-1; a >= 0; a--)   B[--C[(A[a]>>d)&255]] = A[a];
        T = A, A = B, B = T;
    }   
}
int S0[MaxN], S1[MaxN];
main() {
    freopen("in1.txt", "rt", stdin);  
    freopen("out1.txt", "w+t", stdout);
    int n = 0, a;
    clock_t st, ed;
    st = clock();
    while(scanf("%d", &S0[n]) == 1) n++;
    RadixSort(S0, S1, n);
   /*for(a = 0; a < n; a++)
        printf("%d ", S0[a]);
    puts("");*/
    ed = clock();
    printf("%f\n", (float)(ed - st )/CLOCKS_PER_SEC);
    return 0;
}

3.Merge sort
#include <stdio.h>
#include<time.h>
void MergeSort(int, int);
void Merge(int, int, int);
int Data[10000001], X[10000001];
int main() {
    freopen("in1.txt", "rt", stdin);  
    freopen("out3.txt", "w+t", stdout);
    clock_t st, ed;
    st = clock();
    int n = 0;
    while(scanf("%d", &Data[n]) == 1) n++;
    MergeSort(0, n-1);
    /*
    for(i = 0; i < n; i++)
        printf("%d ", numbers[i]);*/
    ed = clock();
    printf("%f\n", (float)(ed - st )/CLOCKS_PER_SEC);
    return 0;
}
void MergeSort(int l, int h) {
    if(l < h) {
        int m = (l+h)/2;
        MergeSort(l, m);
        MergeSort(m+1, h);
        Merge(l, m, h);
    }
}
void Merge(int l, int m, int h) {
    int In1 = l, In2 = m+1;
    int a, b, Top = 0;
    while(In1 <= m && In2 <= h) {
        if(Data[In1] < Data[In2])
            X[Top++] = Data[In1++];
        else
            X[Top++] = Data[In2++];
    }
    while(In1 <= m) X[Top++] = Data[In1++];
    while(In2 <= h)    X[Top++] = Data[In2++];
    for(a = 0, b = l; a < Top; a++, b++)
        Data[b] = X[a];
}
感謝 example & leopan0922
chchwy 2011-10-09 22:17:16

很有用的結果,推一個。不過輸入應該要排除在計時之外吧,還有heap sort 輸出要O(nlogn)這句話,我不太懂耶?