今天的這個比較神奇,是乙個線性複雜度的排序演算法o(n),演算法導論在這一部分先證明了比較排序的複雜度下界是nlgn,所以基數排序不是基於比較的排序。
其實這種比較方法我們應該都接觸過。假設輸入的數都是三位以下的數(當然其他位數也可以,模擬一下,這裡就假設是三位數、兩位數、一位數),那麼只需要大致3n的複雜度就可以排好序。過程是這樣:
先設定輔助空間t[0..9][n]
然後掃第一遍n個數,個位是幾就放在t[幾]那一行。然後掃一遍t陣列,按順序放回原陣列中
然後掃第二遍n個數,十位是幾就放在t[幾]那一行。然後掃一遍t陣列,按順序放回原陣列中
然後掃第三遍n個數,百位是幾就放在t[幾]那一行。然後掃一遍t陣列,按順序放回原陣列中
現在原陣列已經是按順序排好的了。其實就是最原始的比較方法,先比較個位,再比較十位,再比較百位。
**如下:(這裡為了好理解先用冗長的**,其實這裡的**還可以再簡化,然後修改以後適用於任何位數)
#include#includeint 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#includeint 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次排序。注意 按位排序必須是穩定排序,所以在這我選擇了計數排序。具體...
計數排序和基數排序
計數排序和基數排序是屬於線性級時間複雜度的排序方式,雖然沒有冒泡,選擇,快排演算法那些讓人廣為所知,但是這兩種排序方式在某些場合非常適用。計數排序是基數排序的基礎,最為關鍵的是 基數排序演算法是字尾陣列的關鍵 當然字尾陣列也可以用快排 字尾陣列是用於處理字串的一種非常優秀的資料結構,可以高效的處理很...