归并排序 详解「建议收藏」

归并排序 详解「建议收藏」注:内容,图片来自于慕课网liuyubobobo老师的课程。算法复杂度:O(nlogn);也许有很多同学说,原来也学过很多O(n^2)或者O(n^3)的排序算法,有的可能优化一下能到O(n)的时间复杂度,但是在计算机中都是很快的执行完了,没有看出来算法优化的步骤,那么我想说有可能是你当时使用的测试用例太小了,我们可以简单的做一下比较:当数据量很大的时候nlogn的优势将会比…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

注:内容,图片来自于慕课网liuyubobobo老师的课程。

官方代码链接:https://github.com/liuyubobobo/Play-with-Algorithms

算法复杂度:O(nlogn)

也许有很多同学说,原来也学过很多O(n^2)或者O(n^3)的排序算法,有的可能优化一下能到O(n)的时间复杂度,但是在计算机中都是很快的执行完了,没有看出来算法优化的步骤,那么我想说有可能是你当时使用的测试用例太小了,我们可以简单的做一下比较:

 

归并排序 详解「建议收藏」

当数据量很大的时候 nlogn的优势将会比n^2越来越大,当n=10^5的时候,nlogn的算法要比n^2的算法快6000倍,那么6000倍是什么概念呢,就是如果我们要处理一个数据集,用nlogn的算法要处理一天的话,用n^2的算法将要处理6020天。这就基本相当于是15年。一个优化改进的算法可能比一个比一个笨的算法速度快了许多,这就是为什么我们要学习算法。

核心思想:分治。

下面我们来看归并排序的思路(先讲思路再来具体讲归并的细节)

 

归并排序(Merge Sort)

 

归并排序 详解「建议收藏」

 

 

 

当我们要排序这样一个数组的时候,归并排序法首先将这个数组分成一半。如图:

归并排序 详解「建议收藏」

 

 

 

然后想办法把左边的数组给排序,右边的数组给排序,之后呢再将它们归并起来。当然了当我们对左边的数组和右边的素组进行排序的时候,再分别将左边的数组和右边的数组分成一半,然后对每一个部分先排序,再归并。如图:

归并排序 详解「建议收藏」

 

 

 

对于上面的每一个部分呢,我们依然是先将他们分半,再归并,如图:

归并排序 详解「建议收藏」

 

 

 

分到一定细度的时候,每一个部分就只有一个元素了,那么我们此时不用排序,对他们进行一次简单的归并就好了。如图:

归并排序 详解「建议收藏」

 

 

 

归并到上一个层级之后继续归并,归并到更高的层级,如图:

归并排序 详解「建议收藏」

 

 

 

直至最后归并完成。

归并排序 详解「建议收藏」

 

 

 

那么如何归并呢?我们是否可以用O(n)的算法将两个数组归并到一起形成一个数组呢?如果可以的话,我们将可以用递归的过程来实现整个归并。这是你想起来很简单但是操作起来并不是那么简单的问题。

 

 

归并细节:

比如有两个已经排序好的数组,如何将他归并成一个数组?

我们可以开辟一个临时数组来辅助我们的归并。也就是说他比我们插入排序也好,选择排序也好多使用了存储的空间,也就是说他需要o(n)的额外空间来完成这个排序。只不过现在计算机中时间的效率要比空间的效率重要的多。无论是内存也好还是硬盘也好可以存储的数据越来越多,所以设计一个算法,时间复杂度是要优先考虑的。

 

 

 

整体来讲我们要使用三个索引来在数组内进行追踪。

归并排序 详解「建议收藏」

 

 

 

 

 

 

蓝色的箭头表示最终选择的位置,而红色的箭头表示两个数组当前要比较的元素,比如当前是2与1比较,1比2小,所以1放到蓝色的箭头中,蓝色的箭头后移,1的箭头后移。

 

归并排序 详解「建议收藏」

 

 

 

 

然后2与4比较,2比4小那么2到蓝色的箭头中,蓝色箭头后移,2后移,继续比较…….

归并排序 详解「建议收藏」

 

 

归并思路就是这样了,最后唯一需要注意的是那个先比较完的话,那么剩下的直接不需要比较,把后面的直接移上去就可以了,这个需要提前判定一下。

 

归并排序代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

void merge(int a[],int l,int r,int mid)
{
  int aux[r-l+1],i,j,k;
  
  for(k=l;k<=r;k++)
  aux[k-l]=a[k];
  
  i=l;
  j=mid+1;
  for(k=l;k<=r;k++)
  {
  	if(i>mid)
  	{
  		a[k]=aux[j-l];
  		j++;
	  }
	else if(j>r)
	{
		a[k]=aux[i-l];
		i++;
	  }
	else if(aux[i-l]>aux[j-l])
	{
		a[k]=aux[j-l];
		j++;
		}
	else
	{
		a[k]=aux[i-l];
		i++;
			}
				    
  	
	  }	
	
}

void merge_sort(int a[],int l,int r)
{
    if(l>=r)
	return ;
	
	int mid=(l+r)/2;
	
	merge_sort(a,l,mid);
	merge_sort(a,mid+1,r);
	merge(a,l,r,mid);	
	
}


void mergesort(int a[],int l,int r)
{
	merge_sort(a,l,r-1);
}

int main()
{
	int a[105],n,i;
	scanf("%d",&n);
	
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	
	mergesort(a,0,n);
	
	for(i=0;i<n;i++)
	printf("%d ",a[i]);
	
	
	return 0;
 } 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/169882.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Tomcat下的appBase和docBase[通俗易懂]

    我们先看appBase,这个目录表示:1这个目录下面的子目录将自动被部署为应用。2这个目录下面的.war文件将被自动解压缩并部署为应用而docBase只是指向了你某个应用的目录,这个可以和appBase没有任何关系。总结:如果你想自己指定路径,那么应该在docBase里面如果你想简单,那么直接把他们复制到appBase下面就行了如果你把他们弄重复了,也就是2个指向了

    2022年4月7日
    547
  • 计算机网络体系结构综述(上)[通俗易懂]

    计算机网络体系结构综述(上)[通俗易懂]计算机网络体系结构标准的制定使得两台计算机能够像两个知心朋友那样能够互相准确理解对方的意思并做出优雅的回应。本文首先概述了计算机网络体系结构的提出动机,并结合日常生活中的邮政系统介绍了设计的理念,并给出了相关的基本概念和标准。进一步地,我们着重概述了计算机网络体系结构的分层原理及其最重要的组成部分——协议,使得读者能够对计算网路体系结构有一个全新的、系统的认识。

    2022年7月12日
    14
  • 设计模式:组合模式

    设计模式:组合模式

    2022年1月18日
    41
  • 免费ip代理池创建[通俗易懂]

    免费ip代理池创建[通俗易懂]反爬技术越来越成熟,为了爬取目标数据,必须对爬虫的请求进行伪装,骗过目标系统,目标系统通过判断请求的访问频次或请求参数将疑似爬虫的ip进行封禁,要求进行安全验证,通过python的第三方库faker可以随机生成header伪装请求头,并且减缓爬虫的爬取速度,能很好的避过多数目标系统的反扒机制,但对一些安全等级较高的系统,也有极大的可能ip被封禁,当ip被封禁后,通过更换代理ip便可以继续爬取,所以具有一个有效的ip代理池是非常重要的,网上有很多动态ip代理提供商,但如果能有一个自己免费的ip代…

    2022年6月3日
    39
  • 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明[通俗易懂]

    工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明[通俗易懂]工作流WebService接口使用说明一、检查部署是否成功:输入下面的地址http://192.168.4.183(换成实际的地址):8060(实际的端口号)/services/,界面中有如下服务即可:采用WebServerice技术进行协同系统和业务系统进行数据交互,由协同系统方开发实现WebServerice服务,业务系统方需在本地实现WebServerice本地代理来进行调用。…

    2022年6月23日
    37
  • java拦截器_Java拦截器[通俗易懂]

    java拦截器_Java拦截器[通俗易懂]拦截器,主要用于拦截前端请求,常用于登录检查。下面是演示使用拦截器拦截未登录的用户访问需要登录的模块情景,使用配置方式实现和注解方式实现代码:配置方式:1、web.xml中配置监听器,对于所有的/admin开头的请求,都走com.blog.interceptor.LoginInterceptor这个拦截器。2、再看com.blog.interceptor.LoginInterceptor的实现代码…

    2022年4月29日
    184

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号