C语言实现桶排序

 

 

#include<stdio.h>

/*

应该设置几个桶,桶的个数buckerCount:    数组长度length/3 + 1

每个桶最多存放几个元素,桶的容量BuckerSize:    5个

如何确定到达了数组中的存放的最后一个元素
    定义一个数组elemInBucket存放桶中元素个数(空间),或者:
    找到数组中的最小元素,将桶中所有元素的都设置为defaultFigure = min - 1(时间)
    这个程序使用的是第二种方法

如何确定每个桶中存放的元素的范围
    找到最大最小值,计算差值d,根据差值计算每个桶之间的步长step
    step = d / 桶的个数buckerCount + 1
    第k个桶中的元素的范围应该是  min + (k-1) * step < elem < min + k * atep

如何判断应该存放到哪个桶中
     k = (element - min) / step;

*/

void findPosiInBucket(int bucket[][5], int arr[], int k, int i, int defaultFigure, int bucketSize, int bucketCount);
void putInLeft(int bucket[][5], int arr[], int k, int i, int defaultFigure, int bucketSize, int bucketCount, int bucketLeftPosi);
void putInRight(int bucket[][5], int arr[], int k, int i, int defaultFigure, int bucketSize, int bucketCount, int bucketRightPosi);
void printBucket(int bucket[][5], int bucketSize, int bucketCount);
void bucketSort(int bucket[][5], int bucketCount, int bucketSize);
void sortForFive(int bucket[][5],int bucketCount,int bucketSize,int i);
void sortForThree(int bucket[][5],int bucketCount,int bucketSize,int i);

int main() {

    //未排序前的数组
    //int arr[] = {18, 11, 28, 45, 23, 50};
    //int arr[] = {18, 16, 6, 87, 1, 67, 4, 66, 46, 41, 6, 67, 61, 64, 67, 16, 97, 97, 100, 11, 28, 45, 23, 50};
    int arr[] = {18, 11, 28, 45, 23, 50, 27, 44, 71, 92};


    //数组的长度
    int length = sizeof(arr) / sizeof(int);
    int bucketCount = length / 3 + 1;
    int bucketSize = 5;

    //输出排序前的数组
    printf("排序前的数组:");
    for(int i = 0; i < length; i++) {
        printf(" %d ", arr[i]);
    }
    printf("\n");

    //二维数组作为桶
    int bucket[bucketCount][bucketSize];

    //找到最大最小值
    int max = arr[0];
    int min = arr[0];
    for(int i = 0; i < length; i++) {
        if(arr[i] > max)
            max = arr[i];
        if(arr[i] < min)
            min = arr[i];
    }

    //定义桶中的默认元素defaultFigure
    int defaultFigure = min - 1;

    //定义步长step
    int step = (max - min) / bucketCount + 1;

    //给桶中所有元素赋值为默认值
    for(int i = 0; i < bucketCount; i++)
        for(int j = 0; j < bucketSize; j++)
            bucket[i][j] = defaultFigure;

    //将数据放到对应的桶中
    for(int i = 0; i < length; i++) {
        int k = (arr[i] - min) / step;  //应该放到下标为k的桶中
        int temp = 0;

        while(bucket[k][temp] != defaultFigure && temp++ < bucketSize); //找到数组下标为k的桶中的空位置

        if(temp == bucketSize) {    //如果temp等于bucketSize了说明桶中放不下这个元素了
            findPosiInBucket(bucket, arr, k, i, defaultFigure, bucketSize, bucketCount);
        } else {            //正常情况
            bucket[k][temp] = arr[i];
        }
    }

    //对桶中的元素进行排序
    bucketSort(bucket, bucketCount, bucketSize);

    //各个桶之间的排序完成
    //将桶中的数据放回原数组
    int temp = 0;   //存放arr数组下标
    for(int i = 0; i < bucketCount; i++) {
        for(int j = 0; j < bucketSize; j++) {
            if(bucket[i][j] != defaultFigure)
                arr[temp++] = bucket[i][j];
        }
    }

    //输出排序后的数组
    printf("排序后的数组:");
    for(int i = 0; i < length; i++)
        printf(" %d ", arr[i]);
    printf("\n");

    return 0;
}

void findPosiInBucket(int bucket[][5], int arr[], int k, int i, int defaultFigure, int bucketSize, int bucketCount) {
    //找到左右两边距离最近的有位置的桶
    int bucketLeftPosi = k - 1;
    while(bucket[bucketLeftPosi][bucketSize - 1] != defaultFigure && bucketLeftPosi != 0) {
        bucketLeftPosi--;
    }

    int bucketRightPosi = k + 1;
    while(bucket[bucketRightPosi][bucketSize - 1] != defaultFigure && bucketRightPosi != bucketCount - 1) {
        bucketRightPosi++;
    }

    if((k - bucketLeftPosi) <= (bucketRightPosi - k)) { //说明左边空位置近
        putInLeft(bucket, arr, k, i, defaultFigure, bucketSize, bucketCount, bucketLeftPosi);
    } else { //右边空出位置的桶近
        putInRight(bucket, arr, k, i, defaultFigure, bucketSize, bucketCount, bucketRightPosi);
    }
    return ;
}

void putInLeft(int bucket[][5], int arr[], int k, int i, int defaultFigure, int bucketSize, int bucketCount, int bucketLeftPosi) {
    //依次找到最小的数依次放过去
    for(int j = 0; j < k - bucketLeftPosi; j++) {
        //找到第k-j个桶里最小的数与数组元素交换

        //找到最小的元素的位置
        int minPosi = 0;
        for(int t = 0; t < bucketSize && bucket[k - j][t] != defaultFigure; t++) {
            if(bucket[k - j][t] < bucket[k - j][minPosi])
                minPosi = t;
        }

        if(bucket[k - j][minPosi] > arr[i])
            minPosi = -1;

        //把最小的元素与数组交换
        if(minPosi != -1) {   //如果等于-1就不需要做处理
            int temp = arr[i];
            arr[i] = bucket[k - j][minPosi];
            bucket[k - j][minPosi] = temp;
        }
    }

    //当前桶有位置,把数组中的元素放进来
    //找到空位置
    int temp = 0;
    while(bucket[bucketLeftPosi][temp] != defaultFigure && temp++ < bucketSize); //找到数组下标为k的桶中的空位置

    //放进来数组元素
    bucket[bucketLeftPosi][temp] = arr[i];

    return ;
}

void putInRight(int bucket[][5], int arr[], int k, int i, int defaultFigure, int bucketSize, int bucketCount, int bucketRightPosi) {
    //依次找到最大的数依次放过去
    for(int j = 0; j < bucketRightPosi - k; j++) {
        //找到第k+j个桶里最小的数与数组元素交换

        //找到最小的元素的位置
        int maxPosi = 0;
        for(int t = 0; t < bucketSize && bucket[k + j][t] != defaultFigure; t++) {
            if(bucket[k + j][t] < bucket[k + j][maxPosi])
                maxPosi = t;
        }

        if(bucket[k + j][maxPosi] > arr[i])
            maxPosi = -1;

        //把最小的元素与数组交换
        if(maxPosi != -1) {   //如果等于-1就不需要做处理
            int temp = arr[i];
            arr[i] = bucket[k + j][maxPosi];
            bucket[k + j][maxPosi] = temp;
        }
    }

    //当前桶有位置,把数组中的元素放进来
    //找到空位置
    int temp = 0;
    while(bucket[bucketRightPosi][temp] != defaultFigure && temp++ < bucketSize); //找到数组下标为k的桶中的空位置

    //放进来数组元素
    bucket[bucketRightPosi][temp] = arr[i];

    return ;
}

void printBucket(int bucket[][5], int bucketSize, int bucketCount) {
    for(int i = 0; i < bucketCount; i++) {
        printf("第%d个桶中的数据:", i);
        for(int j = 0; j < bucketSize; j++)
            printf(" %d ", bucket[i][j]);
        printf("\n");
    }
    printf("\n");
    return ;
}

void bucketSort(int bucket[][5], int bucketCount, int bucketSize) {
    for(int i = 0; i < bucketCount; i++) {
        sortForFive(bucket, bucketCount, bucketSize,i);

        sortForThree(bucket, bucketCount, bucketSize,i);
    }
}

void sortForFive(int bucket[][5],int bucketCount,int bucketSize,int i) {

    //定义五个元素中最大元素和最小元素的下标
    int minPosi = 0;
    int maxPosi = 0;

    //找到五个元素中的最大和最小值,分别放到两侧
    for(int j = 1; j < bucketSize; j++)
        if(bucket[i][minPosi] > bucket[i][j])
            minPosi = j;

    //最大的元素放到右侧,最小的放到左侧,交换
    int temp = 0;

    if(minPosi != 0) {
        temp = bucket[i][0];
        bucket[i][0] = bucket[i][minPosi];
        bucket[i][minPosi] = temp;
    }

    for(int j = 1; j < bucketSize; j++)
        if(bucket[i][maxPosi] < bucket[i][j])
            maxPosi = j;

    if(maxPosi != bucketSize - 1) {
        temp = bucket[i][bucketSize - 1];
        bucket[i][bucketSize - 1] = bucket[i][maxPosi];
        bucket[i][maxPosi] = temp;
    }
}

void sortForThree(int bucket[][5],int bucketCount,int bucketSize,int i){
//找到中间三个个元素中的最大和最小值,分别放到两侧
        int minPosi = 1;
        int maxPosi = 0;
        for(int j = 2; j < bucketSize - 1; j++) {
            if(bucket[i][minPosi] > bucket[i][j])
                minPosi = j;
            if(bucket[i][maxPosi] < bucket[i][j])
                maxPosi = j;
        }

        //最大的元素放到右侧,最小的放到左侧,交换
        int temp = 0;

        if(minPosi != 1) {
            temp = bucket[i][1];
            bucket[i][1] = bucket[i][minPosi];
            bucket[i][minPosi] = temp;
        }

        if(maxPosi != bucketSize - 2) {
            temp = bucket[i][bucketSize - 2];
            bucket[i][bucketSize - 2] = bucket[i][maxPosi];
            bucket[i][maxPosi] = temp;
        }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值