ChatGPT:为什么计数排序需要进行累加操作
第一种写法
private static void countSort() {int[] MaxMin = findMaxMin();int max = MaxMin[0];int min = MaxMin[1];int[] counts = new int[max - min + 1];for (int num : nums) {counts[num - min]++;}int index = 0;for (int i = 0; i < counts.length; i++) {while (counts[i] > 0) {nums[index++] = min + i;counts[i]--;}}System.out.println(Arrays.toString(nums));}private static int[] findMaxMin() {int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;for (int num : nums) {if (num > max) {max = num;}if (num < min) {min = num;}}return new int[]{max, min};}
第二种写法
/*** Gets the maximum and minimum values in the array** @param arr* @return*/
private static int[] getMinAndMax(int[] arr) {int maxValue = arr[0];int minValue = arr[0];for (int i = 0; i < arr.length; i++) {if (arr[i] > maxValue) {maxValue = arr[i];} else if (arr[i] < minValue) {minValue = arr[i];}}return new int[] { minValue, maxValue };
}/*** Counting Sort** @param arr* @return*/
public static int[] countingSort(int[] arr) {if (arr.length < 2) {return arr;}int[] extremum = getMinAndMax(arr);int minValue = extremum[0];int maxValue = extremum[1];int[] countArr = new int[maxValue - minValue + 1];int[] result = new int[arr.length];for (int i = 0; i < arr.length; i++) {countArr[arr[i] - minValue] += 1;}for (int i = 1; i < countArr.length; i++) {countArr[i] += countArr[i - 1];}for (int i = arr.length - 1; i >= 0; i--) {int idx = countArr[arr[i] - minValue] - 1;result[idx] = arr[i];countArr[arr[i] - minValue] -= 1;}return result;
}
为什么要累积计数(对计数数组 countArr 进行累积,得到每个值的最终位置索引)这相对于第一个方法有什么优化?
累积计数是为了确保基数排序(Counting Sort)的稳定性,并且直接构建出排序后的新数组。以下是累积计数的具体优势及其相对于第一个方法的优化:
1. 稳定性
稳定性指的是在排序过程中,相同的元素保持其原有的相对顺序。累积计数的步骤确保了这一点:
- 累积计数:累积计数数组
countArr
记录了每个元素在最终排序数组中的位置索引。这意味着当我们从右向左遍历原数组时,相同元素会按照原有的顺序被放置到结果数组中。 - 稳定排序:这种方法保证了排序的稳定性,使得相同的元素在排序后保持相对位置不变。这在处理需要稳定排序的情况下(如基于某个关键字排序的多级排序)特别有用。
2. 直接构建排序后的新数组
- 新数组:累积计数方法直接构建了一个新的排序数组
result
。这避免了对原数组的多次操作,提高了代码的清晰度和可维护性。 - 相对索引:累积计数数组
countArr
的值表示原数组中每个元素的最终位置。这使得我们可以一次性将元素放置到正确的位置,避免了在原数组上进行多次遍历和修改。