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

版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/u014328804/article/details/72593840

比较排序的性能极限:

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

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


计数排序(Counting Sort)


简单概括:

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

对待排序序列的限制:

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

优点:

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

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

伪代码:

//输入:待排序数组A,输入元素的界k
//输出:排序后的结果数组B
COUNTING-SORT(A, B, k)
1	let C[0..k] be a new array
2	for i = 0 to k
3		C[i] = 0
4	for j = 1 to A.length
5		C[A[j]] += 1
6	//C[i] now contains the number of elements equal to i
7	for i = 1 to k
8		C[i] += C[i-1]
9	//C[i] now contains the number of elements less than or equal to i
10	for j = A.length downto 1
11		B[C[A[j]]] = A[j]
12		C[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,关键字域个数d
RADIX-SORT(A, d)
1	for i = 1 to d
2		use a stable sort to sort array A on digit i

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

坚持,加油!!!微笑

展开阅读全文

没有更多推荐了,返回首页