排序(Count Sort)

  • 平均时间复杂度:O(n+k)
  • 最好情况:O(n+k)
  • 最坏情况:O(n+k)
  • 空间复杂度:O(k)
  • 排序方式:外部
  • 稳定性:稳定

    C++代码实现

    1. int countSort(vector<int>& arr,int min=NULL,int max=NULL)
    2. {
    3. if(min == NULL) min = *min_element(arr.begin(), arr.end());
    4. if(max == NULL) max = *max_element(arr.begin(), arr.end());
    5. int len = max - min + 1, offset = 0;
    6. if(min < 0) offset = abs(min);
    7. int barrel[len];
    8. memset(barrel, 0, sizeof(barrel));
    9. for(const auto& val:arr){
    10. barrel[val + offset]++;
    11. }
    12. /* //不稳定
    13. vector<int>::iterator it=arr.begin();
    14. for(int i=0;i<len;i++){
    15. while(barrel[i]!=0){
    16. *it=i-offset;
    17. it++;
    18. barrel[i]--;
    19. }
    20. }
    21. */
    22. //稳定写法
    23. vector<int> record(arr.begin(),arr.end());
    24. for(int i = 1; i < len; i++) {
    25. barrel[i] += barrel[i-1];
    26. }
    27. for(int i = record.size() -1; i >= 0; i--){
    28. arr[--barrel[record[i] + offset]] = record[i];
    29. }
    30. }

1. 算法步骤

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

2. 动图演示

countingSort.gif