自适应网站做1920的,表白网站建设源码,布吉网站建设哪家便宜,wordpress foxplayerP. S.#xff1a;以下代码均在VS2019环境下测试#xff0c;不代表所有编译器均可通过。 P. S.#xff1a;测试代码均未展示头文件stdio.h的声明#xff0c;使用时请自行添加。 博主主页#xff1a;LiUEEEEE … P. S.以下代码均在VS2019环境下测试不代表所有编译器均可通过。 P. S.测试代码均未展示头文件stdio.h的声明使用时请自行添加。 博主主页LiUEEEEE C语言专栏 数据结构专栏 力扣牛客经典题目专栏 目录 1、归并排序的基本思想2、归并排序的实现2.1. 归并排序的递归实现2.2. 归并排序的非递归实现 3、归并排序非递归方法实现的常见问题4、结语 1、归并排序的基本思想 归并排序的基本思想
归并排序MERGE-SORT是建立在归并操作上的一种有效的排序算法,该算法是采用分治法Divide andConquer的一个非常典型的应用。将已有序的子序列合并得到完全有序的序列即先使每个子序列有序再使子序列段间有序。若将两个有序表合并成一个有序表称为二路归并。 归并排序核心步骤
2、归并排序的实现 归并排序的实现拥有两种方法
递归实现非递归实现 但归根到底其主要思想不会发生变化以下是归并排序的动态展示图
2.1. 归并排序的递归实现 如上文所展示的效果图可知
对于归并排序需使用二叉树中后序的思想将所给目标数组全部类二分而后进行递归当所递归数组个数为1时开始归并。将归并后的子数组复制到原数组中对应位置并开启新一轮的归并这就需要我们动态开辟一个第三方数组tmp来进行辅助。 归并排序的递归实现代码如下所示
void MergeSort(int* a, int* tmp, int begin, int end)
{if (begin end)return;int mid (begin end) / 2;MergeSort(a, tmp, begin, mid);MergeSort(a, tmp, mid 1, end);int begin1 begin, end1 mid;int begin2 mid 1, end2 end;int i begin;while (begin1 end1 begin2 end2){if (a[begin1] a[begin2]){tmp[i] a[begin1];}else{tmp[i] a[begin2];}}while (begin1 end1){tmp[i] a[begin1];}while (begin2 end2){tmp[i] a[begin2];}memcpy(a begin, tmp begin, (end - begin 1) * sizeof(int));
}2.2. 归并排序的非递归实现 其思想与递归并无差别区别在于操作方式
在递归实现中我们使用类二分的方法将原目标数组分为2份依次进行二分的归并递归而在非递归中我们不再使用类二分的方法而是直接在原数组上进行操作。在逻辑上认为原数组已经进行处于递归的过程即令gap 1第一次对每一个元素进行归并归并完成后令 gap * 2。第二次对每两个元素进行归并归并完成后令 gap * 2。…第n 次对每2^(n-1)个元素进行归并归并完成后令 gap * 2。直到gap大于元素原本数组个数时结束。 归并排序的非递归实现代码如下
void MergeSortNonR(int* a, int n)
{int* tmp (int*)malloc(sizeof(int) * n);if (tmp NULL){perror(MergeSortNonR: malloc fail);return;}int gap 1;while (gap n){for (int i 0; i n; i 2 * gap){int begin1 i, end1 i gap - 1;int begin2 i gap, end2 i 2 * gap - 1;if (begin2 n)对程序代码的优化防止越界break;if (end2 n)对程序代码的优化防止越界end2 n - 1;int j i;while (begin1 end1 begin2 end2){if (a[begin1] a[begin2])tmp[j] a[begin1];elsetmp[j] a[begin2];}while (begin1 end1)tmp[j] a[begin1];while (begin2 end2)tmp[j] a[begin2];memcpy(a i, tmp i, sizeof(int) * (end2 - i 1));}printf(\n);gap * 2;}free(tmp);tmp NULL;
}3、归并排序非递归方法实现的常见问题 在使用非递归方法实现归并排序时我们通常无法精确掌握其归并数组的左右区间例如下图 图中所展示的示例数组拥有十九个元素但在归并过程中会发生越界行为出现bug。 但通过途中所展示我们不难发现出现越界的数组一般为右子数组当右子树组的右下标出现越界时我们可直接对其右下标进行修正即可当右子树组的左下标越界时就说明左子数组已经归并完成我们可直接跳出循环进行下一次归并直到整个数组归并完成即可。 4、结语 十分感谢您观看我的原创文章。 本文主要用于个人学习和知识分享学习路漫漫如有错误感谢指正。 如需引用注明地址。