如何使用递归实现归并排序

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

数据结构的学习过程中,我们经常会遇到排序算法,其中归并排序是一种高效并且算法复杂度比较简单的一种。在课本的介绍中,大部分都会介绍归并排序算法。但是,每次看书总是觉得很容易,自己尝试去实现时,总是会出错。学习数据结构已经有一段时间了,但是直接让我裸写归并排序的代码,也需要花上不少时间去调试。难道就没有更好的方式让我们记住代码吗?

其实只要我们在写代码时,注意下技巧,便可轻松实现归并排序算法。下面介绍下我使用的方式:

第一步:先写一个合并两个排序好数组的方法,方法名就叫做merge,如下:

    public static void merge(int[] a, int aSize, int[] b, int bSize, int[] c){
		int tempA = 0, tempB = 0, tempC = 0;
		while(tempA < aSize && tempB < bSize){
		    if(a[tempA] > b[tempB]){
			    c[tempC++] = b[tempB++];
			}else{
			    c[tempC++] = a[tempA++];
			}
		}

		while(tempA < aSize){
		    c[tempC++] = a[tempA++];
		}

		while(tempB < bSize){
		    c[tempC++] = b[tempB++];
		}
	}

这个方法非常简单,一共有着5个参数(也可以简化为3个参数),其中a,b数组是待合并数组,aSize,bSize是数组长度(这两个参数可以去掉),c为目标数组。主要的流程就是不断的比较a,b数组的大小,然后将较小数据复制进c中。这里面关键的一点就是使用了3个临时变量,用于标志每个数组对应的位置,这样子可以极大简化我们的代码设计。下面是对应的图示过程:

有了这个方法之后,我们就可以开始写归并排序的主体方法了。写主体方法也很简单,思想就是分治算法。

  • 第一步:就是将大数组分成两个小的数组
  • 第二部:排序这两个数组,使用的是递归排序方法,也就是自己调用自己
  • 第三部:调用上面的合并方法合并起来即可

代码非常简单,直接贴上

        public static void mergeSort(int[] source){
	        //递归出口
		if(source.length == 1) return;

		//将大数组分成两个小数组
		int middle = source.length / 2;
		int[] left = new int[middle];
		for(int i=0; i<middle; i++){
		    left[i] = source[i];
		}

		int[] right = new int[source.length - middle];
		for(int i=middle; i<source.length; i++){
		    right[i-middle] = source[i];
		}

		//对数据进行排序(这里使用递归排序)
		mergeSort(left);
		mergeSort(right);

		//合并排序好的数据
		merge(left, left.length, right, right.length, source);
	}

总结:要记住归并排序算法的核心核心思想:分而治之。

时间: 2024-08-08 14:01:21

如何使用递归实现归并排序的相关文章

数据结构--递归实现归并排序

1 /*通过递归实现归并排序 2 * 具有思路:将要排序的数组不断划分,直到只有一个元素的时候停止: 3 * 这是递归的基准条件,返回进行排序. 4 * 归并排序的时间复杂度:O(NlogN):考虑的是复制数据到workarr和workarr到arr的次数 5 * 6 * */ 7 public class MergeWithRecursion { 8 static int items = 6; 9 static int[] arr = {10,8,9,59,2,4}; 10 public st

怎样使用递归实现归并排序

归并排序:归并排序是建立在归并操作上的一种有效的排序算法,该算法是採用分治法(Divide and Conquer)的一个很典型的应用.将已有序的子序列合并,得到全然有序的序列.即先使每一个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. 数据结构的学习过程中.我们常常会遇到排序算法,当中归并排序是一种高效而且算法复杂度比較简单的一种. 在课本的介绍中,大部分都会介绍归并排序算法.可是,每次看书总是认为非常easy,自己尝试去实现时,总是会出错. 学习数据结构已经有

用递归实现归并排序(不会呀 不知道哪里错了)

#include<iostream> using namespace std; #include<vector> #include "Vector.h" void merge(int num[], int tem[], int lo, int hi); //归并排序 void mergesort(int num[],int tem[], int lo, int hi) { //int *tem01; if (hi - lo == 0 ) tem[lo] = nu

递归实现归并排序

1 /************************************************************************* 2 > File Name: merge_sort.cpp 3 > Author: 4 > Description: 5 > Created Time: Sun 26 Jul 2015 10:15:24 AM HKT 6 *******************************************************

【递归】归并排序

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int a[10000],b[10000],n; 5 6 7 void Merge(int left,int mid,int right) 8 { 9 int l=left,m=mid,k=left; 10 while(l<mid&&m<=right) 11 { 12 if(a[l]<a[m]) 13 { 14 b[k]=a[l]; 15 l++; 16

javascript实现非递归--归并排序

另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并排序,思路如下: * 至底而上的思路,二和一,四和一,最后是一半一半和整. * 循环从左到右依次执行,为了节省空间,我节省了右序列,将原数列的一部分作为右小序列,这一部分不会被覆盖. * 作者:吴伟欣 * */ function mergeSearch(arr) { var len = arr.le

排序算法(四)——归并排序与递归

基本思想 分析归并排序之前,我们先来了解一下分治算法. 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解. 分治算法的一般步骤: (1)分解,将要解决的问题划分成若干规模较小的同类问题: (2)求解,当子问题划分得足够小时,用较简单的方法解决: (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解. 归并排序是分治算法的典型应用. 归并排序先将一个无序的N长数组切成N个有序子序列(只有一个数据的

归并排序与递归

基本思想 分析归并排序之前,我们先来了解一下分治算法. 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解. 分治算法的一般步骤: (1)分解,将要解决的问题划分成若干规模较小的同类问题: (2)求解,当子问题划分得足够小时,用较简单的方法解决: (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解. 归并排序是分治算法的典型应用. 归并排序先将一个无序的N长数组切成N个有序子序列(只有一个数据的

(转)排序算法——归并排序与递归

基本思想 分析归并排序之前,我们先来了解一下分治算法. 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解. 分治算法的一般步骤: (1)分解,将要解决的问题划分成若干规模较小的同类问题: (2)求解,当子问题划分得足够小时,用较简单的方法解决: (3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解. 归并排序是分治算法的典型应用. 归并排序先将一个无序的N长数组切成N个有序子序列(只有一个数据的