[算法导论]计数排序

 
#include
#include

#define Length 8
using namespace std;

void CountSort(int numa[], int numb[], int len, int range);
void Output(int num[], int len);

int main ()
{
	int numa[Length] = {2, 5, 3, 0, 2, 3, 0, 3};
	int numb[Length];//numb的长度可以是length也可以是length+1 涉及到之后的操作不同 
	//int numb[Length + 1];必须比numa的长度大1 因为0位无法利用 原理见函数 
	CountSort(numa, numb, Length, 6);//第四个参数代表的是numb中元素从0到最大值之间可能值的个数 Eg:1,3,5 则参数为6 
	Output(numb, Length);	
} 

void CountSort(int numa[], int numb[], int len, int range)
{
	int numc[range];//range代表的是numb中元素从0到最大值之间可能值的个数 
	for(int i = 0; i < range; i++)
	{
		numc[i] = 0;//对数组numc中的全部元素进行初始化 便于之后进行计数 
	}
	
	for(int i = 0; i < len; i++)
	{
		numc[numa[i]]++;//将numc中元素的大小按照numa中的元素的值进行记录 Eg:numa[i]=3 则numc[3]上的值就必+1 
	}
	
	for(int i = 1; i < range; i++)
	{
		numc[i] += numc[i - 1];
	}//循环结束后 //numc[i]的大小就是比numa[i]小的numa中的元素的个数 
	//numc[0]不一定为0 numa[i]可能=0 
	
	//一定要注意 以下的i是从原数列的最后一位开始进行归位的 否则就不是稳定的排序了!!!!!!! 
	for(int i = len - 1; i >= 0; i--)//一定要注意 此处的i是从后向前!!!! 为了保证是稳定的排序 
	{
	//numb[numc[numa[i]]] = numa[i];
	//若是numb的长度设置为length+1 则应该为上面的语句 	
	//因为是利用numa[i]作为角标进行计算 因此不论numa[i]取什么值都不会使numc[numa[i]]=0 因此numb[0]永远不会被用到 
	//因此numb的初始长度应该比numa的长度大1 
		numb[numc[numa[i]] - 1] = numa[i];	
		////B数组的下标从0开始,C[A[i]]中的元素数量的总和从1开始计数,所以存放到B中时需要减1,才能放到正确的位置上 
		//想象当A中只有一个元素,C[A[i]] = 1,要存放进B中,就是B[C[A[i]]-1]  
		
		numc[numa[i]]--;//避免numa中出现重复元素 因此在使用过一次之后就要将该numc -1
						//以免下次出现重复的numa[i]时numc[numa[i]]被二次使用导致将两个相同元素放入numb中的同一个位置 
						//若是numa为不重复的数列 则有无该语句不会产生影响  
	} 
}

void Output(int num[], int len)
{
    for(int i = 0; i < len; i++)//对应的是numb与numa数组长度相等的情况 
    {
        printf("%d  ", num[i]);
    }
    cout << endl;
}

 

 

 

你可能感兴趣的:(排序,算法导论)