C语言归并排序算法-MergeSort.c

#include "stdio.h"

// 函数声明
void print_array(int how_many, int data[], char *str);
void merge(int a[], int b[], int c[], int how_many);
void mergeSort(int key[], int how_many);

int main(void) {
    const int SIZE = 8;
    int a[SIZE] = {99, 82, 74, 85, 92, 67, 76, 49};
    print_array(SIZE, a, "My grades\n");        // 调用print_many函数,打印合并排序前a数组的数据内容
    printf("\n\n");
    mergeSort(a, SIZE);         // 调用mergesort函数
    print_array(SIZE, a, "My sorted grades\n");         // 调用print_many函数,打印合并排序后a数组的数据内容
    printf("\n\n");

    return 0;
}

// 函数定义
void print_array(int how_many, int data[], char *str) {
    int i = 0;
    printf("%s", str);          // 打印str指针指向的内容

    for (i = 0; i < how_many; i++) {
        printf("data[%d] = %d\t", i, data[i]);      // 打印相关数组位置的数值
    }
    printf("\n");
}

/*使用当前合并函数的前提:被合并的a数组里面的元素和b数组里面的元素都是在自己的数组汇总已有排序。目前是按照从低到高进行排序的*/
void merge(int a[], int b[], int c[], int how_many) {
    int i = 0, j = 0, k = 0;

//    print_array(how_many, a, "合并前a:\n");
//    print_array(how_many, b, "合并前b:\n");
//    print_array(k, c, "合并前c:\n");
//    printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);

    /* 循环判断a数组和b数组的各个子项的值,并将小的数值优先放到c合并数组中*/
    while (i < how_many && j < how_many) {
        if (a[i] < b[j]) {
            c[k++] = a[i++];
//            print_array(how_many, a, "a1\n");
//            print_array(k, c, "c1\n");
//            printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
        } else {
            c[k++] = b[j++];
//            print_array(how_many, b, "b1\n");
//            print_array(k, c, "c1\n");
//            printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
        }
//        print_array(how_many, a, "while1 a:\n");
//        print_array(how_many, b, "while1 b:\n");
//        print_array(k, c, "while1 c: \n");
//        printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
    }
    /* 当上述循环操作完成后,a数组的数组还未判断到最后一位,就将a数组中的元素通过while循环复制给c合并数组*/
    while (i < how_many) {
        c[k++] = a[i++];
//        print_array(how_many, a, "a2\n");
//        print_array(k, c, "c2\n");
//        printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
    }
//    print_array(how_many, a, "while2 a:\n");
//    print_array(how_many, b, "while2 b:\n");
//    print_array(k, c, "while2 c: \n");
//    printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
    /* 当上述循环操作完成后,b数组的数组还未判断到最后一位,就将b数组中的元素通过while循环复制给c合并数组*/
    while (j < how_many) {
        c[k++] = b[j++];
//        print_array(how_many, b, "b2\n");
//        print_array(k, c, "c2\n");
//        printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
    }
//    print_array(how_many, a, "while3 a:\n");
//    print_array(how_many, b, "while3 b:\n");
//    print_array(k, c, "while3 c: \n");
//    printf("i = %d, j = %d, k = %d, how_many = %d\n\n", i, j, k, how_many);
}

void mergeSort(int key[], int how_many) {
    int j = 0, k = 1;
    int w[how_many];

    for (k = 1; k < how_many; k *= 2) {     // 获取到合并数组的最大长度,目前是2的倍数
//        print_array(how_many, key, "计算前1:");
//        printf("j = %d, k = %d, how_many = %d", j, k, how_many);
//        printf("\n");
        for (j = 0; j < how_many - k; j += 2 * k) {     // 获取到每次运算的子数组的最大长度,目前也是2的倍数,只是初始化为0
//            print_array(how_many, key, "计算内前1:");
//            printf("j = %d, k = %d, how_many = %d", j, k, how_many);
//            printf("\n");
            merge(key + j, key + j + k, w + j, k);      // w数组作为key + j 和 key + j + k 的合并数组,k 为合并数组的最大长度;且w数组作为合并后的数据的接收方。且调取merge()函,并将相关的实参传递过期
//            print_array(how_many, key, "计算内key1:");
//            print_array(how_many, w, "计算内w1:");
//            printf("j = %d, k = %d, how_many = %d", j, k, how_many);
//            printf("\n");
        }
        /* 将w数组内的内容复制给key数组 */
        for (j = 0; j < how_many; j++) {
            key[j] = w[j];      // 将w数组内的内容复制给key数组
//            print_array(how_many, key, "计算内key2:");
//            print_array(how_many, w, "计算内w2:");
//            printf("j = %d, k = %d, how_many = %d", j, k, how_many);
//            printf("\n");
        }
//        print_array(how_many, key, "计算后key:");
//        print_array(how_many, w, "计算后w:");
//        printf("j = %d, k = %d, how_many = %d", j, k, how_many);
//        printf("\n");
    }
}

解释上述原理:

定义三个函数:

  1. void print_array(int how_many, int data[], char *str):无返回参数的print_array()函数,其中形式参数为:数组长度、int类型的数组指针data、字符指针str。函数的作用是打印字符指针指向的内容以及data指针指向的数组内的内容。
  2. void merge(int a[], int b[], int c[], int how_many):无返回参数的merge()函数,其中形式参数为:int类型的数组指针a、int类型的数组指针b、int类型的数组指针c、以及数组a和数组b的长度。函数的作用是将a数组和b数组内的内容进行从小到高排序并合并到数组c。
  3. void mergeSort(int key[], int how_many):无返回参数的mergeSort()函数,其中形式参数为:int类型的数组指针key、数组的长度。函数的作用是通过将key指针指向的数组,按照相关的逻辑将数组进行排序操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值