归并排序 分治+递归

0      1    2     3     4     5     6     7     8   //下标

{  9  ,  4  ,  3  ,  7  ,  3  ,  8  ,  2  ,  4  ,  8  }//通过mergesort函数递归 来切 开始的时候fir=0, las=8, mid=4  所以下标0-4,分为前组   5-8分为后组

{  9  , 4   ,  3  ,  7  ,  3 }{ 8   , 2   , 4  ,  8  }

{  9   , 4  ,  3 }{  7  , 3 }{ 8   , 2  }{ 4  ,  8  }

{  9   , 4 }{ 3 }{  7  }{3 }{ 8 }{ 2  }{ 4  }{ 8 }

{  9 }{ 4 }{ 3 }{  7  }{3 }{ 8 }{ 2  }{ 4  }{  8 }

-------------------到现在为止,就已经用mergesort() 切割完了, 所有的子集fir==las, 不会再分了,  这时开始递归分治.之前mergesort()里的mergearr()会开始执行

{ 4  ,   9 }{ 3 }{  7  }{ 3 }{ 8 }{ 2  }{ 4  }{  8 }   最先的两个数会首先按大小排序好. 存到数组tem再返回到数组a .  所以4 和9 虽然换位子了, 但是占的还是原来的这两个位置.

{ 3  ,   4  , 9 }{  3  ,   7 }{ 2  ,  8 }{  4  ,   8  }  这是次递归.

{ 3 ,    3 ,  4 ,    7  ,   9}{  2 ,   4 ,   8  ,   8  }

{ 2,     3 ,  3 ,    4  ,   4 ,   7  ,  8 ,   8  ,   9 } 结束,输出a数组;

怕排版坏掉,传上图.

#include<stdio.h>
int a[500]={9,4,3,7,3,8,2,4,8};
int tem[500];
void mergearr(int fir,int mid,int las)//  分治法, 最先合并的是最前面两个数字.
{
	int i=fir,j=mid+1;
	int n=mid,m=las;
	int k=0;
	while(i<=n&&j<=m)
	{
		if(a[i]<a[j])
	    	tem[k++]=a[i++];
		else
			tem[k++]=a[j++];
	}
	while(i<=n)
	{
		tem[k++]=a[i++];
	}
	while(j<=m)
	{
		tem[k++]=a[j++];
	}
	for(i=0;fir<=las;)
	{
		a[fir++]=tem[i++];
	}
}
void mergesort(int fir,int las)//切开成小段
{
	int mid;
	if(fir<las)
	{
	    mid=(fir+las)/2;
		mergesort(fir,mid);
		mergesort(mid+1,las);
		mergearr(fir,mid,las);
	}
}

int main()
{
	int i,n;
	n=9;
	mergesort(0,8);
	for(i=0;i<n;i++)
	{
		printf("%d\n",a[i]);
	}
	while(1);
	return 0;
}

归并排序 分治+递归

时间: 2024-08-10 20:09:36

归并排序 分治+递归的相关文章

4.比较排序之归并排序(递归)

归并排序里运用到算法里很重要的一个思想——分治法:将原问题分解为几个规模较小但类似于原问题的子问题——<算法导论>.在每一层递归中都有3个步骤: 1.分解问题 2.解决问题 3.合并问题的解 举例待排序数组:{6, 5, 3, 1, 7, 2, 4},将它原始序列做分解. 可以经过不断的递归分解可以看到已经把原始数组序列不断分解为最小单位,接下来不妨将它们看做是二叉树的叶子节点. 将他们进行两两归并排序形成二叉树(也称为2路归并算法),可见二叉树的根节点即为最终序列.在这个过程中我们完成了剩余

分治递归:求数组元素的最大值,最小值

//分治递归,求数组元素的最大值,最小值 /** * 保存产生的最大值,最小值 * @author Administrator * */ public class Values { private int max; private int min; public Values(int max,int min){ this.max=max; this.min=min; } public int getMax() { return max; } public void setMax(int max)

归并排序的递归与非递归实现java

package com.edu.hpu.sort.merge; import com.edu.hpu.sort.Sort; public class MergeSort extends Sort { @Override public int[] doSort(int[] arr) { return mergeSort2(arr, 0, arr.length - 1); } @SuppressWarnings("unused") private int [] mergeSort(int

Python归并排序(递归实现)

为什么归并排序如此有用?1. 快捷和稳定归并排序成为?一个非常棒的排序算法主要是因为它的快捷和稳定.它的复杂度即使在最差情况下都是O(n log n).而快速排序在最差情况下的复杂度是O(n^2),当n=20的时候,它比归并要慢4.6倍. 2.容易实现 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #coding:utf-8 def merge_sort(array):     length = le

排序算法之归并排序(递归实现)

[归并排序的思想] 归并排序的思想是如果子数组L和子数组R都是有序的,那么我们可以将其合并为一个有序数组:在归并排序中,首先将子数组的长度设为1,此时每个元素都是一个有序子数组,通过两两合并,我们可以得到若干个长度为2的有序子数组,然后对这些长度为2的子数组两两合并,就可以得若干个到长度为4的有序子数组--------如此下去,最终将合并为一个有序的数组. 下面用一个例子来说明: 假设有数组A[]={25 ,5 ,71, 1, 61, 11, 59 ,15, 48 ,19} 步骤一:(25)(5

归并排序的递归实现

思路图来自:https://www.cnblogs.com/fanwencong/p/5910503.html 这里我们依然用顺序表来实现这个排序算法. 顺序表一样是0号位不用. 这里我们的归并排序是二路归并,思路就是把序列一直分解成两份,直至分到子序列的长度为1,那么显然子序列已经有序,然后再不停地将有序序列归并起来,最后实现排序. 下面上代码: 先是顺序表的接口与声明: #define OVERFLOW 0 #define ERROR 0 #define FALSE 0 #define OK

归并排序(非递归,Java实现)

归并排序(非递归): public class MergeSort { /** * @param arr 待排序的数组 * @param left 本次归并的左边界 * @param mid 本次归并的中间位置,也就是分界线 * @param right 本次归并的右边界 * @param <T> 泛型 * @local aux 辅助空间(Auxiliary Space) */ private static <T extends Comparable<? super T>&g

归并排序(递归、非递归、以及自然归并排序)算法总结

注:本文所指归并排序指 二路归并排序. 归并排序是平均情况.最坏情况.最好情况时间复杂度都为O(Nlog2N)的稳定的排序算法.最近梳理了下归并排序的递归.非递归.以及自然归并排序算法. 归并排序的基础:将两个有序数组合并为一个有序数组,需要O(n)的辅助空间. 图片来自:https://www.cnblogs.com/chengxiao/p/6194356.html // array:待排序数组 //temparray: 临时数组 //startindex:起始下标 //middleindex

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

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