归并排序算法

一.算法思想理解

1.归并排序算法用的是分治思想,就是把复杂的问题分成简单的问题来解决。

2.解题思路:合并两个有序的数组大家应该都会吧(不难,后面也会讲哒),那么,我们如果将一个乱序数组从中间一直切分,一直切分到只有一个数时,这一个数组成的数组就可以看成是有序的,也就是到这一步我们的数组都是有序的了。然后我们再返回去,就是将这些有序的数组两两合并成新的有序数组,之后再合并,直到合并成了一个有序数组,就是我们的答案啦。

我们来举个例子:

(1)将无序数组按照一分为二一直划分成单个数字,此时,每一个数字我们可以看成是有序数组

    

(2)合并有序数组:

我们合并两个有序数组,使之仍然有序的方法是:从两个数组的头一个元素开始,比较取出最小的数放入结果数组,再比较剩下部分的开头元素。

比如:

a1: 2 4 6 -->  2  4  6  -->  _  4  6  -->  _  4  6     -->  _  _  6         -->  _  _  6           -->  _  _  _

a2: 1 3 5 -->  _  3  5  -->  _  3  5  -->  _  _  5     -->  _  _  5         -->  _  _  _           -->  _  _  _

a:            --> 1           -->  1  2      -->  1  2  3     -->  1  2  3  4     -->  1  2  3  4  5   -->  1  2  3  4  5  6

那么,我们接下来再将刚刚分成的有序数组合并

就得到答案啦!

聪明的小伙伴可能发现了,解题的过程就是一层层的分,直到最小,再一层层的合,合成一个,这不就可以用递归来实现嘛!

二.代码实现

#include <iostream>
using namespace std;

#define MAX 10000
int tem[MAX];        // 用于暂时存储合并后的数组

/*
 *该函数用于合并两个有序数列[array_left,array_right),[array_right,end)
 *newArray[]      暂时存储合并后的数组
 *array[]         原始数组
 */
void merge(int newArray[],int array[],int array_left,int array_right,int end)
{
  int l = array_left,r = array_right,p = array_left;

//两个数组都没结束,l,r分别为两有序数列的开头
  while(l < array_right && r < end) 
  {
  	if(array[l] > array[r])
		  newArray[p++] = array[r++];
		else
		  newArray[p++] = array[l++];
	} 

//解决剩下没放进去的数
	while(l < array_right)         
	  newArray[p++] = array[l++];
	while(r < end)
	  newArray[p++] = array[r++];

//讲结果放到原始数组中
	for(int i = array_left; i < end; i++)
	{
		array[i] = newArray[i];
	}
} 


/*
 *归并函数
 *利用递归,分到只有一个元素为止,回退时将其合并
 */
void merge_sort(int l,int r,int a[])
{
	if(l >= r - 1) //只有一个元素 
	{
	  return;
	}

//分
	int mid = (r + l) / 2;
	merge_sort(l,mid,a);
	merge_sort(mid,r,a);

//合
	merge(tem,a,l,mid,r);
}


int main()
{
	int n, a[MAX];
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	merge_sort(0,n,a);
	for (int i = 0; i < n; i++)
	  cout << a[i] << " ";
	return 0;
}

over!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值