演算法導論5 基數排序和計數排序 2016 1 5

2022-04-21 21:46:19 字數 1818 閱讀 1709

今天的這個比較神奇,是乙個線性複雜度的排序演算法o(n),演算法導論在這一部分先證明了比較排序的複雜度下界是nlgn,所以基數排序不是基於比較的排序。

其實這種比較方法我們應該都接觸過。假設輸入的數都是三位以下的數(當然其他位數也可以,模擬一下,這裡就假設是三位數、兩位數、一位數),那麼只需要大致3n的複雜度就可以排好序。過程是這樣:

先設定輔助空間t[0..9][n]

然後掃第一遍n個數,個位是幾就放在t[幾]那一行。然後掃一遍t陣列,按順序放回原陣列中

然後掃第二遍n個數,十位是幾就放在t[幾]那一行。然後掃一遍t陣列,按順序放回原陣列中

然後掃第三遍n個數,百位是幾就放在t[幾]那一行。然後掃一遍t陣列,按順序放回原陣列中

現在原陣列已經是按順序排好的了。其實就是最原始的比較方法,先比較個位,再比較十位,再比較百位。

**如下:(這裡為了好理解先用冗長的**,其實這裡的**還可以再簡化,然後修改以後適用於任何位數)

#include#include

int t[10][20

];int cou[10

];void jishusort(int *a,int l,int

r)

int c=l;

for (i=0;i<=9;i++)

}memset(cou,

0,sizeof

(cou));

memset(t,

0,sizeof

(t));

for (i=l;i<=r;i++)

c=l;

for (i=0;i<=9;i++)

}memset(cou,

0,sizeof

(cou));

memset(t,

0,sizeof

(t));

for (i=l;i<=r;i++)

c=l;

for (i=0;i<=9;i++)

}

}int

main()

;

for (i=1;i<=n;i++)

jishusort(a,

1,n);

for (i=1;i<=n;i++)

return0;

}

在這之前,書中還講了乙個計數排序,也是一種線性複雜度的演算法。大體思想是這樣:如果輸入的數一定在1..k之間,那麼對於每乙個輸入的元素x,確定出小組x的元素個數。利用這一資訊就可以直接把x放在輸出陣列的相應位置了。演算法導論裡的偽**真的太厲害了,用了幾個線性的操作就實現了上面的思想。

下面是**:(按照輸入的數不超過100寫的)

#include#include

int c[101

];void ji4shusort(int *a,int *b,int k,int

n)

for (i=1;i<=k;i++)

for (i=1;i<=n;i++)

for (i=1;i<=n;i++) a[i]=b[i];

}int

main()

,b[20]={};

int max=0

;

for (i=1;i<=n;i++)

ji4shusort(a,b,max,n);

for (i=1;i<=n;i++)

return0;

}

可以注意到上面兩個演算法基本上只適用於排整數。

然後書上又講了桶排序,目測雖然思想和基數排序差不多,但好像略複雜一些,以後有機會再研究。部分習題也不好意思先略過了。

排序 5 基數排序和計數排序

前面介紹的幾種排序方式都是比較式的排序,今天,我們來介紹兩種非比較排序。計數排序和基數排序。1.基本思想 遍歷待排陣列,找到陣列中最大的元素,然後開闢乙個比這個最大元素大1的新陣列,以新陣列的下標表示待排元素,統計原陣列中所有元素出現的個數放在新陣列相應的位置,然後把新陣列中除過0次出現的其餘元素,...

演算法導論 基數排序

時間複雜度 o n 基本思路 兩個數比較大小,我們的直觀感覺是先比較高位,若相同則比較低位。但是這樣做需要記錄額外的資料,浪費空間。而基數排序則是先比較低位,再比較高位。通過各個位的比較進行排序,如果陣列元素最大有n位,則總共需要n次排序。注意 按位排序必須是穩定排序,所以在這我選擇了計數排序。具體...

計數排序和基數排序

計數排序和基數排序是屬於線性級時間複雜度的排序方式,雖然沒有冒泡,選擇,快排演算法那些讓人廣為所知,但是這兩種排序方式在某些場合非常適用。計數排序是基數排序的基礎,最為關鍵的是 基數排序演算法是字尾陣列的關鍵 當然字尾陣列也可以用快排 字尾陣列是用於處理字串的一種非常優秀的資料結構,可以高效的處理很...