完整的计数排序

计数排序要求数据的大小范围已知,可以将待排序的数据一一映射到一个计数器。这个计数器一般用数据来表示。如人的年龄:1-200; 字符串:0-255;
或者 对1000-2000之间的数排序,则可以映射到数组0-1000。 当然也可以在整个整数空间内计数,a[Max],但是这样的空间成本太大;

#include <iostream>

using namespace std;


void CountSort(char *pStr)
{
   if(pStr==NULL && *pStr=='\0')
  return ;


   int len=strlen(pStr);   
   int index=0;
   int table[256]={0};
   
   char *ptemp=new char[len+1];
   ptemp[len]='\0';


   for(int i=0;i<len;++i)
   {
  index=(int)(pStr[i]);
  ++table[index];
   }


   //找到每个元素的应放的最后的一个位置
   for(i=1;i<256;++i)
   {
  table[i]+=table[i-1];
   }
   //倒着来,保证是稳定的排序
   for(i=len-1;i>=0;--i)
   {
  index=(int)(pStr[i]);
  ptemp[(table[index]-1)]=pStr[i];
  --table[index];
   }
   strcpy(pStr,ptemp);
   delete [] ptemp;
}
int main()
{
   char str[]="wangjianwangaajjdadef";
   CountSort(str);
 
   cout<<strlen(str)<<endl;


   return 0;
}
### 计数排序算法的 C 语言实现 计数排序是一种非比较型整数排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。以下是基于提供的引用内容以及专业知识完成的一个完整计数排序算法 C 语言实现。 #### 函数定义 以下是一个标准的计数排序函数 `counting_sort` 的实现: ```c #include <stdio.h> #include <stdlib.h> void counting_sort(int arr[], int len) { if (len <= 0) return; // 找到最大值和最小值 int max = arr[0], min = arr[0]; for (int i = 1; i < len; i++) { if (arr[i] > max) max = arr[i]; if (arr[i] < min) min = arr[i]; } // 创建计数数组并初始化为0 int range = max - min + 1; int* count_arr = (int*)calloc(range, sizeof(int)); if (!count_arr) { printf("Memory allocation failed\n"); exit(1); } // 统计每个元素出现的次数 for (int i = 0; i < len; i++) { count_arr[arr[i] - min]++; } // 修改计数数组,使其包含实际位置信息 for (int i = 1; i < range; i++) { count_arr[i] += count_arr[i - 1]; } // 输出结果数组 int* output = (int*)malloc(len * sizeof(int)); if (!output) { printf("Memory allocation failed\n"); free(count_arr); exit(1); } // 将原数组中的元素按顺序放入输出数组 for (int i = len - 1; i >= 0; i--) { output[count_arr[arr[i] - min] - 1] = arr[i]; count_arr[arr[i] - min]--; } // 复制回原始数组 for (int i = 0; i < len; i++) { arr[i] = output[i]; } // 释放动态分配的内存 free(count_arr); free(output); } ``` 此代码实现了计数排序的核心逻辑[^2],并通过动态内存管理优化了性能[^3]。 --- #### 时间复杂度分析 计数排序的时间复杂度主要由两个部分组成:遍历输入数组统计频率的操作 \(O(n)\),以及处理计数数组并将结果写入输出数组的操作 \(O(k)\)。因此总时间复杂度为 \(O(n + k)\),其中 \(n\) 是输入数组长度,\(k\) 是数值范围大小。 当 \(k\) 远小于 \(n\) 或接近于常数时,计数排序表现出极高的效率[^4]。 --- #### 空间复杂度分析 计数排序的空间复杂度取决于数值范围 \(k\)。具体来说,需要额外分配一个大小为 \(k\) 的计数数组用于记录频次,这可能导致较大的内存消耗,尤其是在 \(k\) 很大时。 --- #### 使用示例 下面展示如何调用上述 `counting_sort` 函数对一组数据进行排序: ```c int main() { int data[] = {4, 2, 2, 8, 3, 3, 1}; int length = sizeof(data) / sizeof(data[0]); printf("Original array:\n"); for (int i = 0; i < length; i++) { printf("%d ", data[i]); } printf("\n"); counting_sort(data, length); printf("Sorted array:\n"); for (int i = 0; i < length; i++) { printf("%d ", data[i]); } printf("\n"); return 0; } ``` 运行以上程序会得到如下输出: ``` Original array: 4 2 2 8 3 3 1 Sorted array: 1 2 2 3 3 4 8 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值