1. 程式人生 > >線性排序演算法 --- 計數排序,基數排序,桶排序

線性排序演算法 --- 計數排序,基數排序,桶排序

計數排序應用:

J - Jeronimo's List

 Gym - 101466J 

http://codeforces.com/gym/101466/problem/J

線性排序演算法計數排序應該挺好理解的,每次把數字出現的次數記錄下來,然後做成字首,字首就是小於等於當前數的個數。

比如   2,3,0,3,6,2,3,5,首先記錄出現次數 

  0 1 2 3 4 5 6 

  1 0 2 3 0 1 1

然後對這個陣列做一個字首

c[0]    c[1]    c[2]    c[3]    c[4]    c[5]    c[6]
 1         1       3       6          6        7       8 

就是這樣 ,然後排序的時候就   輸出數字對應的地方

如 a[i]= 5   那麼 b[c[a[i]]]=a[i]; 把b 數組裡面 7的位置賦值為5.然後小於等於5的數量-1;

#include<bits/stdc++.h>
using namespace std;
int a[8]= {2,3,0,3,6,2,3,5};
int b[8];
int c[7];

int main() {
    for(int i=0; i<8; i++) {
        c[a[i]]++;
    }
    for(int i=1; i<7; i++) {   //把這個for倒過來就是從大到小
        c[i]=c[i-1]+c[i];
    }
    printf("C陣列:\n");
    for(int i=0; i<7; i++) {
        printf("c[%d]\t",i);
    }
    printf("\n");
    for(int i=0; i<7; i++) {
        printf(" %d\t",c[i]);
    }
    printf("\n");
    printf("排序過程\n");
    for(int i=7; i>=0; i--) {
        b[--c[a[i]]]=a[i];
        for(int i=0; i<7; i++) {
            printf("%d ",b[i]);
        }
        printf("\n");
    }
    return 0;
}

基數排序:

實際上和計數排序沒啥太大的區別 ,計數排序如果數太大,你 C陣列的就要浪費非常大的記憶體,或者根本開不了這麼大的記憶體。

基數排序,就是把每個 位拆分出來,實際上和計數排序差距不大。

12,13,120,33,46,52,3,25

120 12 52 13 33 3 25 46

以最後一位遞增

3 12 13 120 25 33 46 52

在最後一位為遞增基礎上倒數第2位遞增

3 12 13 25 33 46 52 120

最後以 第一位 遞增,就是排序好的

#include<bits/stdc++.h>
using namespace std;
int a[8]= {12,13,120,33,46,52,3,25};
int b[8];
int c[10];
int main() {
    int mx=0,pos=0,cot=1;
    for(int i=0; i<8; i++) {
        mx=max(mx,a[i]);
    }
    while(mx/cot>0) {
        memset(c,0,sizeof(c));
        for(int i=0; i<8; i++) {
            c[a[i]/cot%10]++;
        }
        for(int i=1; i<10; i++) {   //把這個for倒過來就是從大到小
            c[i]=c[i-1]+c[i];
        }
        printf("計數陣列:\n");
        for(int i=0; i<10; i++) {
            printf("c[%d]\t",i);
        }
        printf("\n");
        for(int i=0; i<10; i++) {
            printf(" %d\t",c[i]);
        }
        printf("\n");
        printf("排序第%d位結果:\n",pos);
        for(int i=7; i>=0; i--) {
            b[--c[a[i]/cot%10]]=a[i];
        }
        for(int i=0; i<8; i++) {
            a[i]=b[i];
        }
        for(int i=0;i<8;i++){
            printf("%d ",a[i]);
        }
        puts("");
        cot*=10;
        pos++;
    }
    return 0;
}

桶排序,實際上和計數排序也差不多,但是到目前位置我還沒用過。

計數排序就相當於 桶的大小為 1 的排序 。(基數排序實際上有點類似於以10 的桶裡面套著一個10 的桶)個人理解

開一個桶的大小   b   然後把他一個數x丟到 x/b 那個桶裡面去,然後把每個桶裡面排序。把桶分成1不就是計數排序。。個人理解

理論上來說:在分佈桶均勻的情況下,是O(n+n*(2-1/n));

有些情況下可能退化成 普通排序一樣的複雜度。

程式碼就不敲了,還沒用過。。。。