经典算法(五)----归并排序----图解法让你快速入门

引言

     只要设计到数据,就会涉及到数据的排序问题,比如给你随机给你五个整数  3,1,5,2,4 。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ?

    答案是多种多样的,比如用插入排序、希尔排序、堆排序、归并排序、快速排序等等,这些排序方法都可以实现对整数排序,而这篇文章要讲的就是归并排序

本文将从以下几个问题对归并排序进行分析和讲解:

  1. 什么是归并排序?
  2. 归并排序的大概过程是什么?
  3. 怎样用代码实现归并排序?
  4. 归并排序的代码详解。

什么是归并排序?

下面看百度百科对归并排序的定义:

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

简单理解:归并排序一个分两大部,第一步分,第二步合。

下面先看一个动图:

归并排序的大概过程是什么?

我们用归并排序讲一个例子来说明,要排序的数组为3,1,5,2,4.

归并排序第一步:分

分采取一份为二的方法(所以这个归并排序又叫二路归并排序)

mid=(first+last)/2(first是最左边,last是最右边),采取前面的公式,分为【first,mid】和【mid+1,last】

如上图所示,直到分成一个一个的数,分的话可以采取递归调用的方法。

再看第二大步:合

合是指把两个数组合成一个数组,而且合成之后数组是有序的。

合成方法:在合成过程中需要一个临时数组来存合成的结果。可以定义两个变量 i 和 j  分别指向两个数组的第一个元素,比较他俩谁小。就是那个对应的元素放到临时数组里面,指向数组的变量后移。只要其中一个变量走到头位置。

如果是其中一个走到头了,但是另一个还未到头,这时候就需要把数组剩余的元素放到临时数组里面。

上面说的是把两个数组合二为一,但是两个数组其实是一个数组中两块不同的部分(用下标区分的),等上面合成结束,就把临时数组放到原数组里面,下面看合代码。

//将两个有序数列a[first...mid]和a[mid...last]合并
void MergeArray(int a[],int first,int mid,int last,int temp[])
{
	int i=first, j=mid+1;
	int m=mid  , n=last;
	int k=0;
	
	while(i<=m&&j<=n)
	{
		if(a[i]<=a[j])
			temp[k++]=a[i++];
		else
			temp[k++]=a[j++];
	}
	
	while(i<=m)
		temp[k++]=a[i++];
		
	while(j<=n)
		temp[k++]=a[j++];
		
	for(i=0;i<k;i++)
		a[first+i]=temp[i];
} 

怎样用代码实现归并排序?

下面看完整的代码

#include<iostream>
using namespace std;

//将两个有序数列a[first...mid]和a[mid...last]合并
void MergeArray(int a[],int first,int mid,int last,int temp[])
{
	int i=first, j=mid+1;
	int m=mid  , n=last;
	int k=0;
	
	while(i<=m&&j<=n)
	{
		if(a[i]<=a[j])
			temp[k++]=a[i++];
		else
			temp[k++]=a[j++];
	}
	
	while(i<=m)
		temp[k++]=a[i++];
		
	while(j<=n)
		temp[k++]=a[j++];
		
	for(i=0;i<k;i++)
		a[first+i]=temp[i];
} 

//归并排序函数    稳定 
void MergeSort(int a[],int first,int last,int temp[])
{
	if(first<last)
	{
		int mid=(first+last)/2;
		MergeSort(a,first,mid,temp);
		MergeSort(a,mid+1,last,temp);
		MergeArray(a,first,mid,last,temp);
	}
}
//输出数组的值
void printf(int arr[],int len)
{
	for(int i=0;i<len;i++)
		cout<<arr[i]<<" "; 
	cout<<endl;
}
int main()
{
	//要排序的数组 
	int arr[]={3, 44,38, 5,47,15,36,26,27,2 ,46,4 ,19,50,48};
	int len=15;//要排序的数组长度 
	int temp[1];
	//排序 
	MergeSort(arr,0,len-1,temp);
	
	//输出 
	printf(arr,len);
	return 0;
}

运行结果:

 

归并排序代码详解

  1. 第一步分,首先要知道怎样分,采取的是递归调用,记得注意递归的结束条件
  2. 第二步合,把两个小数组合成一个大数组,合的过程应该是啥,一定要清楚

本文参考以及引用:

百度百科

图片动画
 

猜你喜欢

转载自blog.csdn.net/weixin_44820625/article/details/106772000