// 计数排序
void CountSort(int arr[], int length)
{ // 序列的最大值决定了数组的长度
int max = arr[0];
for (int i = 0; i < length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
int* countArr = new int[max + 1];
// 将新申请的动态数组内容全部置为初值0
for (int i = 0; i <= max; i++)
{
countArr[i] = 0;
}
// 遍历数组,统计相同的数字出现的个数
for (int i = 0; i < length; i++)
{
countArr[arr[i]]++;
}
int index = 0;
for (int i = 0; i < max+1; i++)
{
for (int j = 0; j < countArr[i]; j++) // 当统计个数为0时,不赋值。
{
arr[index++] = i; // 再赋值回原数组
}
}
}
//如果遇到类似85,78,56,97,96,98,90这样的序列,前面的方法显然浪费了很多的空间。因此不再以原始序列中的最大值max+1作为数组最大长度,而是以原始序列中的最大值max与最小值min之差+1,即max-min+1作为数组最大长度。
// 计数排序(优化版)
int* CountSort(int arr[], int length)
{ // 找出数组中的最大值和最小值
int max = arr[0];
int min = arr[0];
for (int i = 0; i < length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
if (arr[i] < min)
{
min = arr[i];
}
}
int d = max - min;
int* countArr = new int[d + 1];
// 将新申请的动态数组内容全部置为初值0
for (int i = 0; i <= d; i++)
{
countArr[i] = 0;
}
// 遍历数组,统计相同的数字出现的个数
for (int i = 0; i < length; i++)
{
countArr[arr[i] - min]++;
}
// 对统计数组做处理,后面的元素等于前面所有元素之和,找到重复元素的最靠后位置,然后和它相同的元素在它前面,解决了统计数组中相同元素谁在前谁在后的问题,保持了原序列的稳定性排序。这里是在统计数组中之间表示出原序列的绝对位置
int sum = 0;
for (int i = 0; i <= d; i++)
{
sum = sum + countArr[i];
countArr[i] = sum;
}
int* SortArr = new int[d + 1];
int index = 0;
for (int i = length-1; i >= 0; i--)
{
SortArr[countArr[arr[i]-min] - 1] = arr[i];
countArr[arr[i] - min]--;
}
return SortArr;
}
int main()
{
//int array[] = { 5,3,1,6,9,8,4 };
int array[] = { 8,2,2,7,5,7 };
for (int i = 0; i < sizeof(array)/sizeof(int); i++)
{
cout << array[i] << (i != sizeof(array) / sizeof(int) ? " ": "\n");
}
cout << "\n";
int* p = CountSort(array, sizeof(array) / sizeof(int));
int i = 0;
while (i < sizeof(array)/sizeof(int))
{
cout << p[i] << (i == (sizeof(array) / sizeof(int)) ? "\n": " ");
i++;
}
return 0;
}
C ++ 计数排序
最新推荐文章于 2022-08-31 23:26:27 发布