#---2020.5.3 #---第八章·线性时间排序
计数排序
/* * 计数排序 * 时间复杂度为O(n+k) * 使用计数排序须要在全部元素都在一个小的范围内,即k远小于n * 在k=O(n)时。时间复杂度为O(n) */
// COUNTING-SORT int* countingSort(int *arr, int len, int k) { int *numCount = new int[k](); int *result = new int[len]; // now C[i] contains the number of elements equal to i for (int i=0; i<len; i++) { numCount[arr[i]]++; } // now C[i] contains the number of elements less than or equal to i for (int i=1; i<k; i++) { numCount[i] += numCount[i-1]; } for (int i=len-1; i>=0; i--) { result[numCount[arr[i]]-1] = arr[i]; numCount[arr[i]]--; } delete[] numCount; return result; }
基数排序
/* * 基数排序 * 是建立在计数排序的基础之上的,计数排序的稳定性非常重要 * 否则基数排序就会出错,比如数组[27, 15, 43, 42],假设子排序过程不稳定 * 则结果就为[15, 27, 43, 42] * 时间复杂度为O(d*(n+k)),在d为常数,k=O(n)时,时间复杂度为O(n) */
// RADIX-SORT int* radixSort(int *arr, int len, int d) { int *A = new int[len]; for (int i=0; i<len; i++) A[i] = arr[i]; for (int j=0; j<d; j++) { int k = 10; int *numCount = new int[k](); int *result = new int[len]; //numCount中存储等于i的元素个数 for (int i=0; i<len; i++) { numCount[getDigit(A[i], j)]++; } //numCount中存储小于等于i的元素个数 for (int i=1; i<k; i++) { numCount[i] += numCount[i-1]; } //从后至前依次对元素进行排序。保证稳定性,也能够从前往后,可是排序就不稳定了 for (int i=len-1; i>=0; i--) { result[numCount[getDigit(A[i], j)]-1] = A[i]; numCount[getDigit(A[i], j)]--; } delete[] A; delete[] numCount; A = result; } return A; } int getDigit(int num, int d) { return (num % (int)pow(10.0, d+1)) / pow(10.0, d); }
桶排序
/* * 桶排序 * 在输入符合均匀分布时,桶排序的效果较好 * 将各个元素分布在n个桶中。每一个桶内再使用插入排序 * 仅仅要各个桶的尺寸的平方和与总的元素数呈线性关系 * 则其时间复杂度就为O(n) */
// BUCKET-SORT int* bucketSort(int *arr, int len, int maxNum) { //建立n个桶 vector<int> *result = new vector<int>[len]; //将各个元素分布到各个桶内 for (int i=0; i<len; i++) { result[(int)((arr[i]/(double)maxNum)*len)].push_back(arr[i]); } for (int i=0; i<len; i++) { int n = result[i].size(); //插入排序 for (int j=1; j<n; j++) { int k = j - 1; int key = result[i][j]; while (k>=0 && result[i][k]>key) { result[i][k+1] = result[i][k]; k--; } result[i][k+1] = key; } } //合并各个桶中的元素 for (int i=0, j=0; j<len; j++) { int length = result[j].size(); for (int k=0; k<length; k++) { arr[i++] = result[j][k]; } } delete[] result; return arr; }