归并排序算法的理解

归并排序:先对两个有序的系列进行合并,合并的时候不断的对两个系列的第一个元素进行比较,把较小的那个移动到最前面成为了第一个元素,那么移动的元素后面的元素就是成为了下次比较的序列的第一个元素,如此不断的取两个系列的第一个元素进行比较。

1 4 5 6     2 7 8 9      第一轮1与2比较  1比2小, 那么1被移动了   4成为了下次要比较的元素了

那么下一轮就是比较4和2   2小就被移动了  那么再次比较的就是4和7了  如此一轮一轮的比较。

//merge two array:对两个有序列进行合并
void merge(int a[], int temp[], int first, int mid, int end)
{
	int i = first, j = mid + 1;
	int m = mid, n = end;
	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 (int i = 0; i < k; i++)/*把存储在临时对象temp中排好序列copy到a中对应的下标上*/
		a[first + i] = temp[i];
}

上面只是对两个有序的系列进行合并,还没有对序列进行排序,那么如何排序了,这里我们要用到递归的思想,就是把序列分成若干个系列再合并,分裂到最后必然小的系列,包含一个元素,一个元素的系列必然是有序的, 然后逆向合并,合并起来的必然是有序的。

void merge_sort(int a[], int first, int last, int temp[])
{
	if (first < last)
	{
		int mid = (first + last) / 2;
		merge_sort(a, first, mid, temp);    //it's let letf have a regular
		merge_sort(a, mid + 1, last, temp); //it's let right have a regular
		merge(a, temp, first, mid, last); //merge two  in  one
	}
}

写个测试代码:

int main()
{
	int a[] = { 1, 8, 6, 7, 9, 45, 68, 100, 5 };

	int k = (sizeof(a) / sizeof(int));

	int *p = new int[k];

	merge_sort(a,0,k-1,p);

	for (int i = 0; i < k; i++)
		cout << a[i] << " ";

	return 0;
}

时间: 2024-08-09 11:48:17

归并排序算法的理解的相关文章

POJ1523(求连用分量数目,tarjan算法原理理解)

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7406   Accepted: 3363 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

必须知道的八大种排序算法【java实现】(三) 归并排序算法、堆排序算法详解

一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序示例: 合并方法: 设r[i-n]由两个有序子表r[i-m]和r[m+1-n]组成,两个子表长度分别为n-i +1.n-m. j=m+1:k=i:i=i; //置两个子表的起始下标及辅助数组的起始下标 若i>m 或j>n,转⑷ //其中一个子表已合并完,比较选取结束 //选取r[i]和r[j]

归并排序算法--java

归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为2-路归并. 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))

算法之-归并排序算法

归并排序是效率还是比较高的算法.其中的分治法是常用的一种解决问题的方法,现在流行的云计算其实就是一种分治法的应用. 所谓的分治法,字面解释就是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个思想在实际工作中的作用非常大,特别是处理大数据和做复杂运算的时候. 归并排序的基础是归并操作merge,即将两个有序数组合并为一个有序数组. 归并排序的算法思路为: 第一次扫描数组,将数组中相邻的两个元素mer

递归分治算法(一)-归并排序算法

前言: 分治法是一种算法设计思想,所谓分治,意为分而治之,是指将一个难以直接解决的大问题,递归的分割成一些规模的较小的问题,以便逐个解决.采用分治法设计的算法通常用到递归算法来实现,故标题为递归分治. 归并排序算法 归并就是将两个或两个以上的有序表合并成一个新的有序表.归并排序就是将无序的待排序的序列分解成若干个有序的子序列,并把有序子序列合并为整体有序序列的过程.一般分为2-路归并排序和多路归并排序. 他的大概流程如下图: 我们来看看java代码怎么写的: package guibing; /

数据结构实践——归并排序算法的改进

本文是针对[数据结构基础系列(9):排序]的项目. [项目 - 归并排序算法的改进] 采用归并排序.快速排序等高效算法进行排序,当数据元素较少时(如n≤64),经常直接使用直接插入排序算法等高复杂度的算法.这样做,会带来一定的好处,例如归并排序减少分配.回收临时存储区域的频次,快速排序减少递归层次等. 试按上面的思路,重新实现归并排序算法. [参考解答] #include <stdio.h> #include <malloc.h> #include <stdlib.h>

01背包算法的理解

01背包问题: 有N件物品和一个最大重量限制为V的背包.第i件物品的重量是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的重量总和不超过V,且价值总和最大.每个物品只有1份,且不可分割 看了01背包算法,言简意赅,但理解起来头昏脑胀,不得要领.尝试解释下对该算法的理解,加深记忆. 假设最优解已经存在,怎么判断一个物品i是否在背包里?  简单,只要知道, 1.c[i]是否大于V, 2.F[i-1][V-c[i]],即没有i物品的情况下,最大重量限制为V-c[i]的最优解. 3.F[i

自底向上的归并排序算法

1.什么是自底向上的归并排序? 说到底,不管是前面说的自顶向下的归并排序还是现在讲的自底向上的归并排序,其实质都是归并. 来看看一个演示过程:          这个就是待排序的数组序列          先将数组序列以2个元素为一组分成4组,每个组内部分成2个子序列进行向上合并           这是合并之后的效果           然后以4个元素为一组分成2组,每个组内部分成2个子序列进行向上合并           这是合并之后的效果           然后以8个元素为一组分成1个组

算法之-归并排序算法,插入排序算法

一.归并排序法 归并排序是效率还是比較高的算法.当中的分治法是经常使用的一种解决这个问题的方法,如今流行的云计算事实上就是一种分治法的应用. 所谓的分治法,字面解释就是"分而治之",就是把一个复杂的问题分成两个或很多其它的同样或相似的子问题,直到最后子问题能够简单的直接求解.原问题的解即子问题的解的合并.这个思想在实际工作中的作用很大,特别是处理大数据和做复杂运算的时候. 归并排序的基础是归并操作merge,即将两个有序数组合并为一个有序数组. 归并排序的算法思路为: 第一次扫描数组,