当前位置: 首页 > news >正文

9.4 归并排序(排序(上))

归并排序(稳定)

文章目录

  • 归并排序(稳定)
    • 9.1 基本概念
    • 9.2 实现
      • 9.2.1 递归算法
      • 9.2.2 非递归算法
    • 9.3 内容补充

9.1 基本概念

核心:有序子列的归并

具体步骤:

  1. 从左至右依次遍历两个数组
  2. 比较每次两数组元素大小,并将较小的元素存入新数组中
  3. 不断操作至遍历结束

伪代码描述:

时间复杂度:O( N )

/*
**作用:归并排序
**注意:L = 左边起始位置,R = 右边起始位置,right_end = 右边重点位置
*/
void merge(element_type A[], element_type tempA[], int L, int R, int right_end)
{left_end = R - 1;	//左边终点位置。假设两子列紧挨tmp = L;	//过渡数组下标的初始位置element_num = right_end - L + 1;//任一子列未复制完就继续循环while (L <= left_end && R <= right_end){if (A[L] <= A[R])tempA[tmp++] = A[L++];elsetempA[tmp++] = A[R++];}while (L <= left_end)tempA[tmp++] = A[L++];	//复制左子列剩余元素while (R <= right_end)tempA[tmp++] = A[R++];	//复制有子列剩余元素//将过渡数组赋值会Afor (; element_num > 0; element_num--)A[--element_num] = tempA[--element_num]
}

9.2 实现

9.2.1 递归算法

分而治之:不断递归调用,将原数组不断分成等长的两个子列,再对两个子列进行归并排序

代码实现:

时间复杂度:O( NlogN )

/*
**作用:将有序的A[L]~A[R-1]和A[R]~A[right_end]归并成一个有序数列
**注意:L = 左边起始位置,R = 右边起始位置, right_end = 右边终点位置
*/
void merge(element_type A[], element_type tmpA[], int L, int R, int right_end)
{int temp, left_end, element_num;temp = L;	//过渡数组其实位置left_end = R - 1;	//左子列终点下标element_num = right_end - L + 1;while (L <= left_end && R <= right_end){if (A[L] <= A[R])tmpA[temp++] = A[L++];	//将左边元素复制到tmpAelsetmpA[temp++] = A[R++];	//将右边元素复制到tmpA}while (L <= left_end)tmpA[temp++] = A[L++];	//复制剩下的左子列元素while (R <= right_end)tmpA[temp++] = A[R++];	//复制剩下的右子列元素for (int i = 0; i < element_num; i++, right_end--)A[right_end] = tmpA[right_end];
}/*
**作用:归并排序的递归算法
**注意:在左右两边分别递归时,传入的center值不能相同,否则会导致元素重复
*/
void MSort(element_type A[], element_type tmpA[], int L, int right_end)
{int center;if (L < right_end){center = (L + right_end) / 2;MSort(A, tmpA, L, center);	//递归解决左边MSort(A, tmpA, center+1, right_end);	//递归解决右边merge(A, tmpA, L, center, right_end);	//合并最后两段子序列}
}/*
**作用:归并排序
*/
void merge_sort(element_type A[], int N)
{element_type *tmpA;tmpA = (element_type*)malloc(N * sizeof(element_type));if (tmpA != NULL){MSort(A, tmpA, 0, N-1);free(tmpA);	//排序结束后释放过渡数组空间}else printf("空间不足");
}

9.2.2 非递归算法

每次分别对两个子序列进行归并,不断循环logN次

代码实现:

时间复杂度:O( NlogN )

/*
**作用:将有序的A[L]~A[R-1]和A[R]~A[right_end]归并成一个有序数列
**注意:1. L = 左边起始位置,R = 右边起始位置, right_end = 右边终点**        位置
**     2. 为了减少数组间互相复制的次数,此merge函数不将过渡数组的值复制**        给A[]
*/
void merge(element_type A[], element_type tmpA[], int L, int R, int right_end)
{int temp, left_end, element_num;temp = L;	//过渡数组其实位置left_end = R - 1;	//左子列终点下标element_num = right_end - L + 1;while (L <= left_end && R <= right_end){if (A[L] <= A[R])tmpA[temp++] = A[L++];	//将左边元素复制到tmpAelsetmpA[temp++] = A[R++];	//将右边元素复制到tmpA}while (L <= left_end)tmpA[temp++] = A[L++];	//复制剩下的左子列元素while (R <= right_end)tmpA[temp++] = A[R++];	//复制剩下的右子列元素
}/*
**作用:归并排序的循环算法,两两归并相邻有序子列
**注意:1. length = 当前有序子列的长度
*/
void merge_pass(element_type A[], element_type tmpA[], int N, int length)
{int i;//注意:为了防止访问数组越界,i < N - 2*lengthfor (i = 0; i < N - 2 * lenght; i += length)//注意right_end,需要减去1merge(A, tmpA, i, i + length, i + length * 2 - 1);if (i + length < N)	//剩余两个子列merge(A, tmpA, i,i + length, N - 1);	//归并最后两个子列else	//仅剩一个子列for (; i < N; i++)tmpA[i] = A[i];
}/*
**作用:归并排序
*/
void merge_sort(element_type A[], int N)
{int length;element_type *tmpA;length = 1;	//子序列初始长度为1tmpA = (element_type*)malloc(N * sizeof(element_type));if (tmpA != NULL){while (length < N){merge_pass(A, tmpA, N, length);length *= 2;merge_pass(tmpA, A, N, length);length *= 2;}free(tmpA);}else printf("空间不足");
}

9.3 内容补充

1. CSDN:一文读懂『归并排序』算法(Merge Sort)(含算法模板)

2. 博客园:归并排序详解及应用

http://www.dtcms.com/a/470834.html

相关文章:

  • 老人摔倒检测的智能视觉分析技术与应用 跌倒检测 儿童摔倒检测 跌倒预警
  • 网站制作 语言选择怎么做h5网站模板免费下载
  • 【Linux】数据链路层 and 其他知识
  • 个人网站怎么做口碑怎么创建小程序卖东西
  • linux下conda未安装的解决方法(离线安装linux下的conda)
  • 不错的免费网站建设动漫画设计与制作是学什么
  • 《3D动作游戏受击反馈:从模板化硬直到沉浸式打击感的开发拆解》
  • QWidget 如何设置GPU渲染
  • 做动漫头像的网站it之家网站源码
  • 网站流量统计分析做外贸网站要注意什么
  • 建设本地端网站美食网页设计作品欣赏
  • 哪个网站看电影做便宜制作网站需要哪些技术
  • SPI接口数模转换DAC手册学习
  • OOALV 没有布局保存按钮解决
  • 网站建设陕西wordpress建站 百度网盘
  • GB28181: 应用层网关 ALG(Application Level Gateway)
  • Linux应用 线程
  • 网站建设公司业务提成多少wordpress 缩略图设置
  • RPC的原理及Go RPC
  • 青岛的网站建设怎做网站
  • 智能网站建设软件有哪些潍坊网络推广个人合作
  • Python下载实战:高效稳定技巧大全
  • 手机如何创建简易网站设计签名免费网站
  • 扎染毕业设计代做网站网站备案和域名备案区别
  • NX581NX600美光SSD固态闪存NX601NX602
  • 网络科技公司网站首页蚌埠做网站有哪些公司
  • 建设网站费用要进固定资产吗易语言做网站教程
  • UE5 测量 -4,长度测量:P10点击按钮清除距离测量,P11最终测量效果。
  • 返回链接 网站惩罚检查 错误检查百度一下官方下载安装
  • 房地产网站方案网络广告策划书案例