首先还是来说说我学习之后的感受:计数排序需要for循环4次,而且所有的内存分两个方面其中之一就是输出数据的指定了和输入的大小是一样的。还有一个就是和输入数据中最大数子密切相关的最大数字有多大就需要多大的内存(二者是线性的关系) 。
计数排序的算法简介(借鉴《算法导论》):
COUNTING-SORT(A , B ,k)
for i = 0 to k
do c[i] = 0
for j = 1 to length(A)
do c[A[j]] = c[A[j]] + 1
for i = 1 to k
do c[i] +=c[i-1]
for j = length(A) downto 1
do B[c[A[j]]] = A[j]
c[A[j]] -= 1
over
思路很简单就是用B来保存输出数据(排好序的数据),c[]是一份辅助空间,用来记录A中从第一个到最后一个元素中对于每一个元素 小于等于它的个数 。 然后利用c[]中的信息对A[]中的元素进行排序 。
典型的空间花费很大,和A[]中最大数字有很大关系 ,基数排序运行时间复杂度是O(n + k)
算法复杂度由于O(nlogn)
下面是我实现的源码(请大家狠批):
#include <iostream>
#include <Windows.h>
using namespace std ;
/* ***** 类的声明 ***** */
template <class T> class CountSort{
public :
CountSort(T a[] ,int sz , int maxval) ;
~CountSort() ;
void Counting_sort() ;
void Print() ;
private:
T* A ;
T* B ;
int size ;
int length ;
};
/* ***** 构造函数 ***** */
template <class T>
CountSort<T>::CountSort(T a[] ,int sz , int maxval)
{
size = sz ;
length = maxval ;
A = new T[sz + 1] ;
B = new T[sz + 1] ;
for (int i = 1 ; i != sz + 1 ; ++i)
{
A[i] = a[i - 1] ;
}
}
/* ***** 析构函数 ***** */
template <class T>
CountSort<T>::~CountSort()
{
delete []A ;
delete []B ;
}
/* ***** 主排序函数 ***** */
template <class T>
void CountSort<T>::Counting_sort()
{
T* C ;
C = new T[length + 1] ;
/* ***** 将统计计数的全部清零 ***** */
memset(C , 0 , sizeof(T) * (length + 1)) ;
/* ***** 统计A中相同元素的个数 ***** */
for (int i = 1 ; i != size + 1 ; ++i)
{
C[A[i]] = C[A[i]] + 1 ;
}
/* ****** 统计小于(等于)指定元素的所有个数 ****** */
for (int i = 1 ; i != length + 1 ; ++i )
{
C[i] = C[i] + C[i - 1] ;
}
for (int i = size ; i != 0 ; --i)
{
B[C[A[i]]] = A[i] ;
C[A[i]] -= 1 ;
}
}
/* ***** 打印排序的结果 ****** */
template <class T>
void CountSort<T>::Print()
{
cout << "The Result of the Counting Sort " << endl ;
for (int i = 1 ; i != size + 1 ; ++i )
{
cout << B[i] << " " ;
}
cout << endl ;
}
/* ***** main函数 ***** */
int main()
{
int a[] = { 2 , 5 , 3 , 0 , 2 , 3 , 0 , 3} ;
CountSort<int> m_count(a , 8 , 5) ;
m_count.Counting_sort() ;
m_count.Print() ;
Sleep(20000) ;
}
敬请各位点评!!!