1. 程式人生 > 其它 >C ++ 計數排序

C ++ 計數排序

技術標籤:c++排序演算法

// 計數排序
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; }