C ++ 計數排序
阿新 • • 發佈:2020-12-28
// 計數排序
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;
}