针对于范围小数量大的数组,直接遍历一次对所有数进行计数,然后自己根据计数结果写数组
void sort(int* arr, int n, int min, int max) //不稳定 { const int RAN = max - min + 1; int* arrRes = (int*)malloc(sizeof(int) * n); int* arrCount = (int*)malloc(sizeof(int) * RAN); //计数数组 for (int i = 0; i < RAN; i++) { arrCount[i] = 0; } for (int i = 0; i < n; i++) { arrCount[arr[i] - min]++; } for (int i = 0, j = 0; i < RAN; i++) { while (arrCount[i] > 0) { arrRes[j] = i + min; j++; arrCount[i]--; } } memcpy(arr, arrRes, sizeof(int) * n); free(arrRes); free(arrCount); }
原来的方法是不稳定的,因为数组是我们自己写的,这次我们把计数数组优化成增量数组,记录每种数最后的排序,然后倒序遍历原数组找到所有位置
void sortP(int* arr, int n, int min, int max) //稳定 { const int RAN = max - min + 1; int* arrRes = (int*)malloc(sizeof(int) * n); int* arrCount = (int*)malloc(sizeof(int) * RAN); for (int i = 0; i < RAN; i++) { arrCount[i] = 0; } for (int i = 0; i < n; i++) { arrCount[arr[i] - min]++; } for (int i = 1; i < RAN; i++) //修改成增量数组,记录每种数字最后一个的排序位置 { arrCount[i] = arrCount[i - 1] + arrCount[i]; } for (int i = n - 1; i >= 0; i--) //倒序获取每个数字位置 { arrRes[arrCount[arr[i] - min] - 1] = arr[i]; arrCount[arr[i] - min]--; } memcpy(arr, arrRes, sizeof(int) * n); free(arrRes); free(arrCount); }
针对特定范围小数量大的数组十分好用