九大排序之——计数排序

来源:互联网 发布:oppoa77t怎么切换网络 编辑:程序博客网 时间:2024/06/02 19:42

计数排序


计数排序步骤:


(1)找出待排序的数组中最大和最小的元素;

(2)统计数组中每个值为i的元素的出现的次数,存入数组C的第i项;

(3)对所有的计数累加;

(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1;


图示:




代码实现:


void CountSort(int* arr, size_t n){assert(arr);int max = 0;for (size_t i = 0; i < n; i++){if (arr[i]>max)max = arr[i];}//计数数组int* tmp = new int[max + 1];memset(arr, 0, sizeof(int)*(max + 1));for (size_t i = 0; i < n; i++){tmp[arr[i]]++;}int index = 0;for (size_t i = 0; i <= max; i++){while (tmp[i]--){arr[index] = i;++index;}}delete[] tmp;}


时间复杂度&空间复杂度&稳定性


时间复杂度:O(N+k)   ----k是要排序的数组的范围

空间复杂度:O(k)

稳定性:稳定


计数排序优化


类似于直接哈希算法,当数组中的元素不是从最小的数开始的,而是像(1000,1002,1003,1004,1000)这样的数组采用计数排序时,如果我们依旧是开辟最大数+1的空间时,就会使前面的空间全部浪费,因此应该找出最大值和最小值,两者相减就会得到对应的临时数组空间的大小,然后对其进行相应的映射,得到排好序的有序序列。


计数排序优化代码实现:


void CountSort(int* arr, size_t n){assert(arr);int max = arr[0];int min = arr[0];for (size_t i = 0; i < n; i++){if (arr[i] > max)max = arr[i];if (arr[i] < min)min = arr[i];}//确定要开辟数组的大小int range = max - min + 1;int* tmp = new int[range];for (size_t i = 0; i < n; i++){tmp[arr[i] - min]++;}//考回原数组int index = 0;for (size_t i = 0; i < range; i++){while (tmp[i]--){arr[index] = i + min;index++;}}delete[] tmp;}

原创粉丝点击