排序算法学习整理四(计数排序)

四、计数排序:

  个人觉得吧,计数排序是最简单的排序算法,就是特别浪费空间,接下来,来点严谨一些的语言:

  计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

  排序思路:  

  1. 找出待排序的数组中最大和最小的元素
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i项
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

  这一本正经的话讲的真累人,其实就是多开一个数组,那个数出现过,新开的数组下标和这个数相等的位置就加1;

  打个比方:

    存在一个数组:1 5 9 4 2 0 0 3 1 4 0

    在这里面 1出现了2次,那么另一个数组array[1]就自加两次,0出现了3次,那么array[0]就自加三次……

    然后就从array中从0开始到n结束,不是array[i]不是0,就填入原数组;

  讲完了思路下面我们来尝试一下写代码,

    嗯,不对,在这之前有个很重要的事情需要说明,由于不知道数组最大值,所以计数排序需要额外定义非常大的数组,不用客气,没炸就行。

  好,开始写代码:

    首先,先定义一个很大的数组

#define N 100000  //将N定义为100000,也可以用const int N = 100000;
int a[N];      //最好定义在函数外面,因为太大了容易把主函数空间撑爆。(不到万不得已,不要在函数外定义变量、数组等等,常量可以)

     接着是计数

	for (int i = 0; i < n; i++)
	{
		a[arr[i]]++;   //这个就是刚刚打比方的地方,记录一个数出现了多少次;   
	}

    最后是排序

	for (int i = 0, j = 0; i < N; i++)
	{
		while (a[i])   //位运算等价于a[i] > 0,利用了非0即为真的特性,不是0就一直循环
		{
			arr[j] = i;  //只要a[i]不为0就赋值给arr[j];
			a[i]--;
			j++;    //移到下一个位置
		}
	}

    下面是完整的代码

 1 #define N 100000
 2 int a[N];
 3 void sort(int *arr, int count)
 4 {
 5     for (int i = 0; i < count; i++)
 6     {
 7         a[arr[i]]++;
 8     }
 9 
10     for (int i = 0, j = 0; i < N; i++)
11     {
12         while (a[i])
13         {
14             arr[j] = i;
15             a[i]--;
16             j++;
17         }
18     }
19 }
View Code

 

  想都不用想计数排序的局限性很大,不仅浪费时间,而且无法给小数排序,而且仅仅在一定范围内速度很快,一旦最大值太大就会非常慢,而且会导致程序崩溃。

下面这种实现方法思路比较奇特,但是是较为正统的技术排序实现方式

  思路图大致如下:

  代码实现如下:

void CountSorted(int length)
{
    int times[MAXSIZE] = {0};
    int res[MAXSIZE] = {0};
    int max = 0;
    for (int i = 0; i < length; i++)
    {
        times[array[i]]++;
        if (max < array[i])
        {
            max = array[i];
        }
    }

    for (int i = 0; i <= max; i++)
    {
        times[i] += times[i - 1];
    }

    for (int i = length - 1; i >= 0; i--)
    {
        res[times[array[i]] - 1] = array[i];
        times[array[i]]--;
    }

    for (int i = 0; i < length; i++)
    {
        array[i] = res[i];
    }
}

 

posted @ 2019-08-01 16:16  秦_殇  阅读(336)  评论(0编辑  收藏  举报