关闭

排序算法总结--归并排序算法

221人阅读 评论(0) 收藏 举报
分类:

归并排序算法

在排序算法中快速排序的效率是非常高的,但是还有种排序算法的效率可以与之媲美,那就是归并排序;归并排序和快速排序有那么点异曲同工之妙,快速排序:是先把数组粗略的排序成两个子数组,然后递归再粗略分两个子数组,直到子数组里面只有一个元素,那么就自然排好序了,可以总结为先排序再递归;归并排序:先什么都不管,把数组分为两个子数组,一直递归把数组划分为两个子数组,直到数组里只有一个元素,这时候才开始排序,让两个数组间排好序,依次按照递归的返回来把两个数组进行排好序,到最后就可以把整个数组排好序;

归并排序时的时间复杂度为O(nlgn) 其主要思想是分治法(divide and conquer),分就是要将n个元素的序列划分为两个序列,再将两个序列划分为4个序列,直到每个序列只有一个元素,最后,再将两个有序序列归并成一个有序的序列。例如两个序列:

要归并成一个有序的序列,按照我们常规的方法,我们每次从两个列表开头元素选取较小的一个,直到某一个列表到达底部,再将另一个剩下部分顺序取出。其实如果将每个元素最后添加一个最大值,则无需判断是否达到列表尽头。

算法的理解其实可以借助下面这个图:

对于原始的数组2,1,3,8,5,7,6,4,10,在整个过程执行的是顺序是途中红色编号1-20。虽然我们描述中说的是程序先分解,再归并,但实际过程是一边分解一边归并,前半部分分先排好序,后半部分再拍好,最后整个归并为一个完整的序列,途中的merge过程它所在层的两个序列的merge过程:下图展示了每个merge过程对作用于数组的哪部分(红色)。

整个过程就像一个动态的树,执行顺序就是对树的先序遍历顺序。

 #include <iostream>
 
 using namespace std;
 
 #define LEN 12 
 int *tmp = new int[LEN]; //注意tmp数组从递归开始至递归结束都是同一个数组,所以只能设置成全局变量,如果在函数内设置则会错误 
 
 // 打印数组  
 void print_array(int *array)  
 {  
     int index = 0;  
     printf("\narray:\n");  
     for (; index < 12; index++){  
         printf(" %d, ", *(array + index));  
     }  
     printf("\n");   
 }  
 
 // 把两个有序的数组排序成一个数组  
 void mergeSortArray(int array[],int start,int mid,int end)
 {
 	 int startFirst = start;
 	 int startLast = mid;
	 int endFirst = mid + 1;	
	 int endLast = end;
	 //int len = end - start + 1; //注意tmp数组从递归开始至递归结束都是同一个数组,所以只能设置成全局变量,如果在函数内设置则会错误 
	 //int tmp[len] = {};
	 int index = start;
	 
	 while((startFirst <= startLast) && (endFirst <= endLast))
	 {
	 	if(array[startFirst] <= array[endFirst])
	 		tmp[index++] = array[startFirst++];
	 	else
		 	tmp[index++] = array[endFirst++];
	 }
	 
	 while(startFirst <= startLast)
	 {
	 	tmp[index++] = array[startFirst++];
	 }
	 
	 while(endFirst <= endLast)
	 {
	 	tmp[index++] = array[endFirst++];
	 }
	 
	 for(startFirst = start; startFirst <= end; startFirst++)
	 {
	 	array[startFirst] = tmp[startFirst];
	 }
 }
 
 void mergeSort(int array[], int start, int end)
 {
 	if(start < end)
 	{
 		int mid = (start + end) / 2;
 		mergeSort(array,start,mid);
		mergeSort(array,mid+1,end);
		mergeSortArray(array,start,mid,end);	
 	}
 	
 }
 int main(void)  
 {  
     int array[LEN] = {2, 1, 4, 0, 12, 520, 2, 9, 5, 3, 13, 14};  
     print_array(array);  
     mergeSort(array, 0, LEN - 1);  
     print_array(array);  
     return 0;  
 } 


0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

【算法总结】归并排序总结

【前言】 归并排序的思想是,将一个数组划分成为可以轻易排序的最小部分(最小部分的标准通常是1个数或者两个数),对最小数组排好序后,向上合并排序数组(向上合并排序通常需要额外空间,譬如:现在两个排好序的...
  • cdnight
  • cdnight
  • 2013-09-16 11:16
  • 1088

2-路归并排序详解

2-路归并排序的核心操作是将一维数组中前后相邻的两个有序序列归并为一个有序序列. 1、算法基本思路      设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+...
  • yunzhongguwu005
  • yunzhongguwu005
  • 2013-07-25 20:57
  • 7607

算法 - 归并排序(C#)

/* * MergeSorter.cs - by Chimomo * * 归并排序是建立在归并操作上的排序算法,该算法是分而治之策略(Divide and Conquer)的一个非常典型的应用...
  • chimomo
  • chimomo
  • 2014-12-03 17:28
  • 2493

归并排序 图解算法过程

归并排序,图解,详细过程。
  • collonn
  • collonn
  • 2013-12-26 14:09
  • 7670

白话经典算法系列之五 归并排序的实现(讲的真好)

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较...
  • yuehailin
  • yuehailin
  • 2017-04-03 16:25
  • 14932

经典排序之多路归并

多路归并排序
  • u010367506
  • u010367506
  • 2014-04-16 21:26
  • 5677

外排序(磁盘排序)之多路归并排序的简单实现

摘要:本文简要介绍了当数据量大到不适合在内存中排序时,利用磁盘进行排序的多路归并算法。 关键字:外排序,磁盘排序,多路归并           下面以一个包含很多个整数的大文件为例,来说明多路归并...
  • qisefengzheng
  • qisefengzheng
  • 2015-05-26 15:31
  • 631

php实现归并排序

php实现归并排序: 这个排序我看了很久,大多数代码是从百度上看到的,因为我也是一个php的菜菜的,不过觉得应该把思路写下来,一方面是自己要总结一下,一方面是自己把思路写出来如果有哪里不对的地方也希...
  • liwuqi123456
  • liwuqi123456
  • 2016-01-17 22:33
  • 397

[STL] List 中sort为什么采用归并排序

这几天在看STL(SGI版本----侯捷),在看完第一章后有点懵,但还是很震撼,STL的设计理念确实很好,至于有多么好我们都懂,所以就不再评价了。      由于刚刚开始看,所以有些东西并不是很透彻,...
  • zr1076311296
  • zr1076311296
  • 2016-05-22 19:07
  • 781

JavaScript排序之归并排序

1.简介 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。归并排序是一个O(nlogn)的算法,其基本思想就是一个分治的策略,先进行划分,然后再进行合并。 ...
  • ansenamerson
  • ansenamerson
  • 2016-09-21 17:30
  • 802
    个人资料
    • 访问:75832次
    • 积分:2273
    • 等级:
    • 排名:第19128名
    • 原创:149篇
    • 转载:71篇
    • 译文:0篇
    • 评论:3条
    最新评论