博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
归并排序MergeSort的C实现
阅读量:6927 次
发布时间:2019-06-27

本文共 1665 字,大约阅读时间需要 5 分钟。

归并排序作为最经典的分治算法之一,本质是利用递归把问题分解至最小子问题(即将原数组分解为只有单个元素的子数组),然后递归开始“回升”,每一层回升都是在合并两个有序数组(依次从两个数组的头部取出较小的元素放入目标数组,某一组全部取出后即可直接依次插入另一数组的所有剩余元素,两组元素全部取完后排序结束),C语言代码如下:

void merge(int arrA[], int lenA, int arrB[], int lenB, int arrTarget[]) {    int iA = 0, iB = 0, iT = 0;    for (; iA < lenA && iB < lenB; iT ++) { // 当两个数组都还有剩余元素时,比较每一个元素并插入        if (arrA[iA] <= arrB[iB]) {            arrTarget[iT] = arr[iA];            iA ++;        } else {            arrTarget[iT] = arr[iB];            iB ++;        }    }    for (; iA < lenA; iA ++, iT ++) arrTarget[iT] = arrA[iA]; // 若数组A还有剩余元素    for (; iB < lenB; iB ++, iT ++) arrTarget[iT] = arrA[iB]; // 若数组B还有剩余元素}

完成了这个merge,其实就已经做完了归并排序的大部分工作,接下来我们只要把前期准备做好就可以了!也就是merge接受的两个输入数组必须是有序的,但是怎么才能从乱序的原始数组中得到两个有序的子数组呢?

这里我们可以使用二分法,也就是将原始数组从中点开始不断往下分割,当每一个子数组都只包含一个元素时,它也就达到了有序状态。而这里,自然也就是递归开始“回升”的节点,merge也可以出现了。
于是整个排序的过程就是:不断二分 -> 触底(完全分割) -> 回升

void mergeSort(int arr[], int fst, int lst, int arrTarget[]) {    if (fst < lst) {        // 二分(此处的函数将会在子数组的fst不大于lst时开始逐层返回,进行合并)        int mid = (fst + lst) / 2;        mergeSort(arr, fst, mid, arrTarget);        mergeSort(arr, mid + 1, lst, arrTarget);        // 合并        merge(arr + fst, mid - fst + 1, arr + mid + 1, lst - mid, arrTarget + fst);    }}

运行结束后,arrTarget就是原数组的有序版本,它可以在main函数中直接定义,不过也可以通过进一步打包函数来避免这种麻烦并减少需要填写的参数:

int* MergeSort(int arr[], int len) {    int* arrTarget = (int*)malloc(sizeof(int) * len);    // 此处不建议直接创建数组,函数结束后所有临时变量的内存都将被释放,任何操作都可能改变这里的数据    if (arrTarget == NULL) { // 内存申请失败        printf("Error: malloc failed.\n");        exit(1);    }    mergeSort(arr, 0, len - 1, arrTarget);    return arrTarget;}

现在只需要填上原始数组和长度就可以得到一个排好序的新数组的指针啦!

转载地址:http://nfujl.baihongyu.com/

你可能感兴趣的文章
Redis技术分享
查看>>
TensorFlow:tf.train.Saver()模型保存与恢复
查看>>
UML图示
查看>>
QEMU KVM Libvirt手册(10): KVM的各种限制
查看>>
错误:“The requested resource () is not available.”的处置
查看>>
Lintcode: Hash Function && Summary: Modular Multiplication, Addition, Power && Summary: 长整形long...
查看>>
CentOS搭建Git服务器及权限管理
查看>>
Kinect控制PowerPoint播放
查看>>
一个js下拉菜单 类似jq效果
查看>>
背景图片百分之百大小css设置方法
查看>>
Google Play和基于Feature的过滤 —— Feature 参考手册
查看>>
背包问题
查看>>
eclipse cdt Program "make" not found in PATH
查看>>
Redis命令拾遗四(集合类型)—包含简单搜索筛选商品设计实例。
查看>>
第二十九章 springboot + zipkin + mysql
查看>>
maven提示invalid LOC header (bad signature)的解决办法
查看>>
classloader example
查看>>
Python sockets - sending string in chunks of 10 bytes - Stack Overflow
查看>>
使用MQ要考虑的问题
查看>>
提升Android应用视觉效果的10个UI技巧【转】
查看>>