七、希尔排序(增量排序)
原理:按增量分组,对每组插入排序,增量逐渐缩小至1。
void shellSort(int arr[], int n) {
int gap, i, j, temp;
for (gap = n/2; gap > 0; gap /= 2) { // 增量序列(常用n/2递减)
for (i = gap; i < n; i++) { // 对每个分组插入排序
temp = arr[i];
for (j = i; j >= gap && arr[j-gap] > temp; j -= gap) // 升序,降序改 <
arr[j] = arr[j-gap];
arr[j] = temp;
}
}
}
八、计数排序(非比较排序,适用于范围已知的整数)
原理:统计元素频率,按频率重构数组。
void countSort(int arr[], int n, int max) { // max为数组最大值
int count[max+1] = {0}, i, j;
for (i = 0; i < n; i++) count[arr[i]]++; // 统计频率
for (i = 1; i <= max; i++) count[i] += count[i-1]; // 计算前缀和(确定位置)
int output[n];
for (i = n-1; i >= 0; i--) { // 稳定排序(从后往前)
output[count[arr[i]]-1] = arr[i];
count[arr[i]]--;
}
for (i = 0; i < n; i++) arr[i] = output[i]; // 复制回原数组
}
九、桶排序(非比较排序,适用于均匀分布数据)
原理:分桶后对每个桶排序,合并结果。
#define BUCKET_SIZE 10 // 桶大小(可自定义)
void bucketSort(int arr[], int n) {
int max = arr[0], i, j;
for (i = 1; i < n; i++) if (arr[i] > max) max = arr[i];
int bucket_count = (max/BUCKET_SIZE) + 1;
int buckets[bucket_count][n], counts[bucket_count] = {0};
// 分配元素到桶
for (i = 0; i < n; i++) {
int idx = arr[i]/BUCKET_SIZE;
buckets[idx][counts[idx]++] = arr[i];
}
// 对每个桶排序(此处用插入排序)
for (i = 0; i < bucket_count; i++) insertionSort(buckets[i], counts[i]);
// 合并桶到原数组
int k = 0;
for (i = 0; i < bucket_count; i++)
for (j = 0; j < counts[i]; j++)
arr[k++] = buckets[i][j];
}
十、基数排序(非比较排序,按位数排序)
原理:从低位到高位依次排序,基于计数排序。
int getMax(int arr[], int n) { // 获取最大值位数
int max = arr[0], i;
for (i = 1; i < n; i++) if (arr[i] > max) max = arr[i];
int digits = 0;
while (max > 0) { max /= 10; digits++; }
return digits;
}
void radixSort(int arr[], int n) {
int exp, i, count[10] = {0}, output[n];
for (exp = 1; getMax(arr, n)/exp > 0; exp *= 10) { // 按位(个位、十位...)
// 统计频率
for (i = 0; i < n; i++) count[(arr[i]/exp)%10]++;
// 计算前缀和
for (i = 1; i < 10; i++) count[i] += count[i-1];
// 稳定排序(从后往前)
for (i = n-1; i >= 0; i--) {
output[count[(arr[i]/exp)%10] - 1] = arr[i];
count[(arr[i]/exp)%10]--;
}
// 复制回原数组
for (i = 0; i < n; i++) arr[i] = output[i];
}
}