淺談基數排序

woc,學完發現本身貌似以前會???ios

這裏簡單介紹一下基數排序。(這是一個穩定的排序哦)git

基數排序是桶排序的擴展具體怎麼擴展我也不知道.數組

基本思想:

  把整數按位切割成不一樣的數字,而後按每一個位數分別比較。spa

具體作法:

  把全部數的數位統一,高位沒有的補零。code

   而後從低位到高位,對每一位進行一次排序。這裏不是用sort(#`O′)!blog

這裏直接給出栗子:排序

{\(102,237,70,167,228,12,202,63,146,92\)}.get

而後首先要變成這個樣子.string

{\(102,237,070,167,228,012,202,063,146,092\)}it

具體的流程以下:(這裏我比較習慣豎着寫咯.)

這個思想是否是超級好懂?

可是!若是咱們對每一次都無序地對這些數排列的話,顯然不能獲得一個有序的序列。

所以咱們基數排序最後須要倒着放回去。(這樣能保證穩定性但我不會證實QAQ)

複雜度分析:

時間複雜度

很明顯,咱們須要排序的次數取決於最可能是幾位數.

時間複雜度爲\(O(n \times maxdigit )\)

空間複雜度

咱們只須要一個臨時數組來記錄新位置上的數是誰,並記錄每一位上的每一個數的出現次數便可。

所以,空間複雜度爲\(O(n)\)

代碼:

剩下的就很少說了,直接放代碼就行了.

代碼

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define R register

using namespace std;

const int gz=1e5+8;

inline void in(R int &x)
{
    R int f=1;x=0;char s=getchar();
    while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    x*=f;
}

int n,a[gz],tmp[gz],cont[10];

inline int get()//求最大位數
{
    R int d=1,p=10;
    for(R int i=1;i<=n;i++)
        while(a[i]>=p)
            p*=10,d++;
    return d;
}

inline void radixsort()//基數排序
{
    R int d=get(),p=1;
    for(R int i=1;i<=d;i++,p*=10)//進行d次排序
    {
        memset(cont,0,sizeof cont);//每次清空計數器。
        for(R int j=1;j<=n;j++)
        {
            R int now=(a[j]/p)%10;//取出當前位上的數
            cont[now]++;//記錄0~9每一個數的出現次數.
        }
        for(R int j=1;j<10;j++)
            cont[j]+=cont[j-1];//求前綴和.
        for(R int j=n;j;j--)//倒放,保證順序.
        {
            R int now=(a[j]/p)%10;
            tmp[cont[now]]=a[j];//放進臨時數組.
            cont[now]--;//這個數的出現次數減一.
        }
        for(R int j=1;j<=n;j++)
            a[j]=tmp[j];//將臨時數組賦給a數組.
    }
}

int main()
{
    in(n);
    for(R int i=1;i<=n;i++)in(a[i]);
    radixsort();
    for(R int i=1;i<=n;i++)
        printf("%d ",a[i]);
}
相關文章
相關標籤/搜索