计数排序(Counting Sort)与基数排序(Radix Sort)小结

来源:互联网 发布:蚌埠市农村金融数据 编辑:程序博客网 时间:2024/06/05 02:10

比较排序的性能极限:

       对于冒泡排序、插入排序、归并排序、堆排序、快速排序等通过将待排序元素进行比较来实现排序的算法,它们有一个时间复杂度的极限,即:最坏情况下有渐进下界:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------


计数排序(Counting Sort)


简单概括:

       计数排序是通过对待排序序列中的每种元素的个数进行计数,然后获得每个元素在排序后的位置的信息的排序算法。

对待排序序列的限制:

       输入序列的n个数必须是在[0, k]区间内的整数,k为某个整数。

优点:

       (1)线性时间复杂度:当时,时间复杂度为:

       (2)稳定性:具有相同值的元素在输出数组中的相对次序不会改变。

伪代码:

//输入:待排序数组A,输入元素的界k//输出:排序后的结果数组BCOUNTING-SORT(A, B, k)1let C[0..k] be a new array2for i = 0 to k3C[i] = 04for j = 1 to A.length5C[A[j]] += 16//C[i] now contains the number of elements equal to i7for i = 1 to k8C[i] += C[i-1]9//C[i] now contains the number of elements less than or equal to i10for j = A.length downto 111B[C[A[j]]] = A[j]12C[A[j]] -= 1

C++代码实现:

#include <iostream>#include <vector>using namespace std;void countingSort(vector<int> &A, vector<int> &B, int k){    vector<int> C(k+1, 0);    for(int i = 0 ; i < (int)A.size() ; ++i)    {        C.at(A.at(i)) += 1;    }    for(int i = 1 ; i <= k ; ++i)    {        C.at(i) += C.at(i-1);    }    for(int i = (int)A.size() - 1 ; i >= 0 ; --i)    {        B.at(C.at(A.at(i)) - 1) = A.at(i);        C.at(A.at(i)) -= 1;    }}int main(){    vector<int> A = {2, 5, 3, 0, 2, 3, 0, 3};    vector<int> B(A.size(), 0);    int k = 5;    cout << "Initial array: ";    for(int i = 0 ; i < (int)A.size() ; ++i)    {        cout << A.at(i) << ", ";    }    cout << endl;    countingSort(A, B, k);    cout << "Sorted array: ";    for(int i = 0 ; i < (int)B.size() ; ++i)    {        cout << B.at(i) << ", ";    }    cout << endl;    return 0;}
输出结果:


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------


基数排序(Radix Sort)


简单概括:

       基数排序用于对多关键字域数据(例如:一副扑克牌,大小可以看做一个关键字域,花色也可以看做另一个关键字域)进行排序,每次对数据按一种关键字域进行排序,然后将该轮排序结果按该关键字的大小顺序堆放,依次进行其他关键字域的排序,最后实现序列的整体排序。

限制:

       基数排序需要一种稳定的排序算法作为子程序,在这里使用计数排序。

时间复杂度:

       (1)给定n个d位k进制数,使用计数排序(耗时:)作为子程序,那么时间复杂度为:,因此,当d为常数,时,为线性代价;

       (2)给定n个b位k进制数,若b太大,可考虑将b分成r段,这时得到n个b/r位k^r进制数,同样使用计数排序(耗时:),那么时间复杂度为:,当时,此时时间复杂度为:

缺点:

       不是原址排序;虽然可以达到线性时间复杂度,但是常数因子较大。

伪代码:

//输入:待排序的数组A,关键字域个数dRADIX-SORT(A, d)1for i = 1 to d2use a stable sort to sort array A on digit i

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

坚持,加油!!!微笑

原创粉丝点击