网站首页 > java教程 正文
情景回顾
上节回顾:如何用C语言实现希尔排序——一种比插入排序更快的排序算法
本节重点
本节重点:归并排序的自上而下递归法——如何用C语言实现一种能让你的电脑爆炸的排序算法,你敢试吗?
关注不迷路
微信公众号:工控小新
学习工控知识就来工控小新,为你提供工控笔记知识:EPLAN电气绘图 | TIA博图基础 | CAD | C语言教学 | 单片机基础 | 三菱PLC ... 每日持续更新中
归并排序是一种基于归并操作的排序算法,它可以将一个无序的序列分成若干个有序的子序列,然后再将这些子序列合并成一个完全有序的序列。归并排序的时间复杂度是O(nlogn),空间复杂度是O(n),它是一种稳定的排序算法,也就是说,它不会改变相同元素的相对顺序。
归并排序有两种实现方法,一种是自上而下的递归方法,另一种是自下而上的迭代方法。在这篇文章中,我们将介绍如何用C语言实现这两种方法,并给出相应的代码示例。
自上而下的递归方法
自上而下的递归方法是一种分治法的典型应用,它的基本思想是:
- 如果序列只有一个元素,那么它已经是有序的,无需排序;
- 如果序列有多个元素,那么将它分成两个(或更多)的子序列,分别对子序列进行归并排序;
- 将排好序的子序列合并成一个有序的序列。
为了实现这个方法,我们需要定义一个辅助函数,用来将两个有序的子序列合并成一个有序的序列。这个函数的参数是:
- 一个待排序的序列(数组)arr;
- 一个临时的存储空间(数组)temp,用来存放合并后的序列,它的大小应该和arr一样;
- 两个子序列的起始索引left和right,以及两个子序列的结束索引mid和end。
这个函数的步骤是:
- 1、定义两个指针i和j,分别指向左右子序列的第一个元素;
- 2、定义一个指针k,指向临时空间的第一个位置;
- 3、比较i和j所指向的元素,将较小的元素复制到临时空间,并移动相应的指针;
- 4、重复上一步,直到某一子序列的所有元素都被复制到临时空间;
- 5、将另一子序列剩余的元素直接复制到临时空间的后面;
- 6、将临时空间的内容复制回原数组的相应位置。
这个函数的C语言代码如下:
// 合并两个有序的子序列
void merge(int arr[], int temp[], int left, int mid, int right)
{
int i = left; // 左子序列的起始索引
int j = mid + 1; // 右子序列的起始索引
int k = left; // 临时空间的起始索引
while(i <= mid && j <= right)
{
// 当两个子序列都有元素时
if(arr[i] <= arr[j])
{
// 如果左子序列的元素小于等于右子序列的元素
temp[k++] = arr[i++];
// 将左子序列的元素复制到临时空间,并移动指针
}
else
{
// 如果右子序列的元素小于左子序列的元素
temp[k++] = arr[j++];
// 将右子序列的元素复制到临时空间,并移动指针
}
}
while(i <= mid)
{
// 当左子序列还有剩余元素时
temp[k++] = arr[i++];
// 将左子序列的剩余元素复制到临时空间
}
while(j <= right)
{
// 当右子序列还有剩余元素时
temp[k++] = arr[j++];
// 将右子序列的剩余元素复制到临时空间
}
for(i = left; i <= right; i++)
{
// 将临时空间的内容复制回原数组
arr[i] = temp[i];
}
}
有了这个辅助函数,我们就可以定义一个递归函数,用来对一个序列进行归并排序。这个函数的参数是:
- 一个待排序的序列(数组)arr;
- 一个临时的存储空间(数组)temp,用来存放合并后的序列,它的大小应该和arr一样;
- 一个序列的起始索引left,和一个序列的结束索引right。
这个函数的步骤是:
- 如果left等于right,那么说明序列只有一个元素,无需排序,直接返回;
- 如果left小于right,那么说明序列有多个元素,需要排序,继续执行以下步骤:
- 计算序列的中间索引mid,将序列分成两个子序列;
- 对左子序列进行归并排序,调用自身函数;
- 对右子序列进行归并排序,调用自身函数;
- 将排好序的左右子序列合并,调用辅助函数。
这个函数的C语言代码如下:
// 对一个序列进行归并排序
void merge_sort(int arr[], int temp[], int left, int right)
{
if(left == right)
{
// 如果序列只有一个元素,无需排序,直接返回
return;
}
if(left < right)
{
// 如果序列有多个元素,需要排序
int mid = (left + right) / 2;
// 计算序列的中间索引,将序列分成两个子序列
merge_sort(arr, temp, left, mid);
// 对左子序列进行归并排序,递归调用
merge_sort(arr, temp, mid + 1, right);
// 对右子序列进行归并排序,递归调用
merge(arr, temp, left, mid, right);
// 将排好序的左右子序列合并,调用辅助函数
}
}
这样,我们就完成了自上而下的递归方法的实现。
- 上一篇: 挑战全网,自下而上的迭代法——飞速运行的归并排序方法
- 下一篇: Java程序员必备的算法与数据结构
猜你喜欢
- 2025-05-27 2025-04-29:高度互不相同的最大塔高和。用go语言,给定一个数组
- 2025-05-27 PHP排序算法:计数、选择、插入、归并、快速、冒泡、希尔、堆
- 2025-05-27 Python高级排序算法应用
- 2025-05-27 用好RANK函数 跨表排名不用愁
- 2025-05-27 十大排序算法时空复杂度
- 2025-05-27 Excel表格通过拆分再合并的方法对合并单元格排序
- 2025-05-27 万能的vlookup,居然能用来合并同类项,这个公式设计的太巧妙了
- 2025-05-27 算法基础:插入排序 实现原理和应用场景
- 2025-05-27 算法之常见排序算法-冒泡排序、归并排序、快速排序
- 2025-05-27 公式很短,将 Excel 合并单元格中的数据行按大小排序
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)