十大排序法3

七、希尔排序(增量排序)

原理:按增量分组,对每组插入排序,增量逐渐缩小至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];  

    }  

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值