C语言常见排序算法归并排序

 更新时间:2022年07月14日 09:04:27   作者:保护小周ღ  
这篇文章主要介绍了C语言常见排序算法归并排序,归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用

前言

本期为大家带来的是常见排序算法中的归并排序,博主在这里先分享归并排序的递归算法,包您一看就会,快来试试吧~

 一、归并排序

1.1 基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法 (Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序 列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

1.2 算法思想

到这里,我们可以得到一条结论,两个有序的子序列可以合成一个新的有序子序列,通过递归,我们两个新的有序序列也可以组成新的有序数列,最终实现排序的目的。有些朋友就会问了,这个我懂,关键是咋实现有序数列,其实非常的简单,分割递归至每个子序列只有一个元素时,是不是就有序啦,然后就可以合成有两个元素有序的列表嘛,再合成4个,8个……

1.3 程序设计思想

定义一个tmp数组,可以是动态开辟的(malloc),用于临时存放合并后的有序数据,定义_MergeSort()函数,用于分解,合并数据(递归实现),参数有,待处理数组,数据区间(数组下标),tmp数组。

  • 判断区间是否存在,区间不存在以及只有一个元素的情况结束程序。
  • 分割区间:mid=(left+right)/2;递归左右区间,分割递归至每个子序列只有一个元素。
  • 每两个子序列一组,循环遍历每一个元素,if比较两个子序列各元素的大小,取大或取小,放入tmp数组,tmp[index++]=子序列++;直到有一个子序列遍历完,循环结束。
  • 循环判断是子序列是否遍历完毕,未遍历完毕的子序列剩余元素直接给到tmp数组。将tmp数组的对应的元素拷贝回原数组(已有序)。

1.4 程序实现

#define _CRT_SECURE_NO_WARNINGS
 
#include<stdio.h>
#include<stdlib.h>//动态开辟空间的函数的头文件
 
void _MergeSort(int *a,int left,int right,int *tmp)
{
	//区间不存在以及只有一个元素的情况结束程序
	if (left>=right)
	{
		return;
	}
 
	int mid = (left + right) / 2;
	//假设[left,mid],[mid+1,right]有序,那么我们就可以归并了
	//递归使左右区间有序
	//分割递归至每个子序列只有一个元素
	_MergeSort(a,left,mid,tmp);
	_MergeSort(a, mid+1,right, tmp);
 
	//归并
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int index = left;
 
	while (begin1<=end1&&begin2<=end2)//有一个子序列遍历完,循环结束
	{
		if (a[begin1] < a[begin2])//升序,取小
		{
			tmp[index++] = a[begin1++];
 
		}
		else
		{
			tmp[index++] = a[begin2++];
		}
	}
 
	//判断子序列是否遍历完,未遍历完毕的子序列剩余元素直接给到tmp数组
	while (begin1 <= end1)
	{
		tmp[index++] = a[begin1++];
	}
 
	while (begin2<=end2)
	{
		tmp[index++] = a[begin2++];
	}
 
	//拷贝回去
	for (int i=left;i<=right;++i)
	{
		a[i] = tmp[i];
	}
}
 
//归并排序
void MergeSort(int *a,int n)
{
	int* tmp=(int*)malloc(sizeof(int)*n);//动态开辟与待排序数组大小相等的一片连续的空间
	_MergeSort(a,0,n-1,tmp);//子函数实现归并
 
	free(tmp);//释放动态开辟的空间
}
 
//打印
void Print(int* a, int n)
{
	for (int i=0;i<n;++i)
	{
		printf("%d ",a[i]);
	}
}
int main()
{
	int a[] = {10,6,7,1,3,9,4,2};
	MergeSort(a,sizeof(a)/sizeof(a[0]));
	Print(a,sizeof(a)/sizeof(a[0]));
	return 0;
}

1.5 归并排序的特性总结

  • 1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问 题。
  • 2. 时间复杂度:O(N*logN)
  • 3. 空间复杂度:O(N)
  • 4. 稳定性:稳定

到此这篇关于C语言常见排序算法归并排序的文章就介绍到这了,更多相关C语言归并排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++使用map实现多进程拷贝文件的程序思路

    C++使用map实现多进程拷贝文件的程序思路

    这篇文章主要介绍了C++使用mmap实现多进程拷贝文件,通过本文给大家分享程序思路及完整代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • VSCode搭建STM32开发环境的实现步骤

    VSCode搭建STM32开发环境的实现步骤

    因为VSCode免费且好用,可以安装各种插件,本文主要介绍了VSCode搭建STM32开发环境的实现步骤,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • C++ 实现高性能HTTP客户端

    C++ 实现高性能HTTP客户端

    HttpClient可以实现所有HTTP的方法,通过API传输接收HTTP消息。本文详细讲解了HttpClient,以及如何运用C++实现HTTP客户端,感兴趣的朋友可以参考一下
    2021-08-08
  • C语言编写简单的定时关机程序

    C语言编写简单的定时关机程序

    本文给大家分享的是一则C语言编写的简单的定时关机程序,可以设置0-600秒倒计时,有需要的小伙伴可以参考下。
    2016-02-02
  • C++类结构体与json相互转换

    C++类结构体与json相互转换

    这篇文章主要介绍的是C++类结构体与json相互转换,json字符串一般使用的是开源的类库Newtonsoft.Json,方法十分简洁,下面就随小编一起看下面文章内容吧
    2021-09-09
  • C语言中二级指针解析(指向指针的指针)

    C语言中二级指针解析(指向指针的指针)

    这篇文章主要介绍了C语言中二级指针(指向指针的指针),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • C/C++实现动态库动态加载

    C/C++实现动态库动态加载

    在很多项目中,我们多少会用到第三方动态库,这些动态库一般都是相对固定,使用也很简单,下面我们就来看看c/c++中如何实现动态库动态加载吧
    2024-01-01
  • C++实现的多重继承功能简单示例

    C++实现的多重继承功能简单示例

    这篇文章主要介绍了C++实现的多重继承功能,结合简单实例形式分析了C++面向对象程序设计中类的定义与继承相关操作实现技巧,需要的朋友可以参考下
    2018-05-05
  • C++ OpenCV裁剪图片时发生报错的解决方式

    C++ OpenCV裁剪图片时发生报错的解决方式

    在图像处理中,我们经常根据需要截取图像中某一区域做处理,下面这篇文章主要给大家介绍了关于C++ OpenCV裁剪图片时发生报错的解决方式,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • C语言实现自动存取款机模拟系统

    C语言实现自动存取款机模拟系统

    这篇文章主要为大家详细介绍了C语言实现自动存取款机模拟系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05

最新评论