排序算法之 计数排序 及其时间复杂度和空间复杂度

       计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。


算法分析

        主要思想:据array数组元素的值进行排序,然后统计大于某元素的元素个数,最后就可以得到某元素的合适位置;比如:array[4] = 9;统计下小于array[4]的元素个数为:8;所以array[4] = 9 应该放在元素的第8个位置;
        主要步骤:
       1、根据array数组,把相应的元素值对应到tmpArray的位置上;
     2、然后根据tmpArray数组元素进行统计大于array数组各个元素的个数;
     3、最后根据上一步统计到的元素,为array元素找到合适的位置,暂时存放到tmp数组中;

        如下图所示:array 是待排序的数组;tmpArray 是相当于桶的概念; tmp 是临时数组,保存array排好序的数组;

        排序算法之 计数排序 及其时间复杂度和空间复杂度_第1张图片

        注意:计数排序对输入元素有严格要求,因为array元素值被用来当作tmpArray数组的下标,所以如果array的元素值为100的话,那么tmpArray数组就要申请101(包括0,也就是 mix - min + 1)。


代码实现

#include
#include
 
 void print_array(int *array, int length)
 {
     int index = 0;
     printf("array:\n");
     for(; index < length; index++){
         printf(" %d,", *(array+index));
     }   
     printf("\n\n");
 }
 
 void countSort(int *array, int length)
 {
   /*
     int *tmpArray = (int*)malloc(sizeof(int)*length);
     int i, j, count;
 
     for (i = 0; i < length; i++) tmpArray[i] = 0;
         
     for (i = 0; i < length; i++){
         for (count = 0, j = 0; j < length; j++){
             if (array[i] < array[j])count++;
         }               
         while(tmpArray[count])count++;
         tmpArray[count] = array[i];
     }   
 
     for (i = 0; i < length; i++)array[i] = tmpArray[i];
 
     free(tmpArray);
  */

     int *tmpArray = (int*)malloc(sizeof(int)*(length+1));//申请内存空间,记得大小为length + 1(因为array元素值为 0~9)
     int tmp[length];
     int i, j, k;
 
     for (i = 0; i < length; i++){ // 初始化数组
         tmpArray[i] = 0;  
         tmp[i] = 0;
     }   
 
     for (i = 0; i < length; i++) tmpArray[array[i]]++; // 表示该桶内有多少个元素
 
     for (i = 1; i <= length; i++) tmpArray[i] += tmpArray[i-1];// 统计大于该元素的元素个数
     
     for (i = length; i > 0; i--){// 这是核心代码了,可以理解为把array数组中的元素存放到合适的位置
         tmp[tmpArray[array[i-1]]-1] = array[i-1];
         tmpArray[array[i-1]]--; // 解决一个桶内有多个元素
     }   
 
     for (i = 0; i < length; i++) array[i] = tmp[i];// 把有序元素放回到array数组中
 
     free(tmpArray);// 是否空间

 }
 int main(void)
 {
 //  int array[] = {12, 1, 32, 201, 9987, 5, 10, 10090, 123, 453};
     int array[] = {2, 1, 3, 0, 9, 5, 1, 7, 4};
     int length = (sizeof(array)) / (sizeof(array[1]));
     print_array(array, length);
     countSort(array, length);
     print_array(array, length);
 
     return 0;
 }
 
  

        运行结果:

        排序算法之 计数排序 及其时间复杂度和空间复杂度_第2张图片


时间复杂度

        时间复杂度可以很好的看出了就是:O( n );


空间复杂度

        空间复杂度也可以很好的看出来:O( n );

总结

        计数排序的时间复杂度和空间复杂度都是非常有效的,但是该算法对输入的元素有限制要求,所以并不是所有的排序都使用该算法;最好的是0~9之间的数值差不会很大的数据元素间比较;有人会说这个没多大用,但是在后面的基数排序中会看到,这可以算是基数排序中的一个基础;

        转载请注明作者和原文出处,原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/44561487
        若有不正确之处,望大家指正,共同学习!谢谢!!!

你可能感兴趣的:(数据结构,面试,排序算法)