【算法导论】归并排序(分治法)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CSDN___CSDN/article/details/83471804

许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关地若干子问题。这些算法典型的遵循分治法地思想:将原问题分解成几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。

分治模式在每层递归时都有三个步骤:

  • 分解原问题为若干子问题,这些子问题是原问题规模较小的实例。
  • 解决这些子问题,递归地求解各子问题。若子问题规模足够小,则直接求解。
  • 合并这些子问题的解成原问题的解。

归并排序:完全遵循分治模式。

  • 分解:分解该待排序的n个元素的序列成各具n/2元素的两个子序列。
  • 解决:使用归并排序递归地解决两个子序列。
  • 合并:合并两个已排序的子序列以产生以排序的答案。

归并排序示意图:

归并排序C语言代码实现:

从大到小的排序:

//归并排序 
#include "stdio.h"
#include "math.h"
#include "time.h"
#include "stdlib.h"
#define MAXSIZE 1000
#define INF -100000
int array[MAXSIZE];
int start,finish;
int main ()
{
	start=clock();
	int len;
	void merge_sort(int array[],int p,int r);
	void merge(int array[],int p,int q,int r);
	printf("输入数组元素个数:\n"); 
	scanf("%d",&len);
	for(int i=1;i<=len;i++)
	{
		array[i]=(rand()%10000);
	}
	printf("排序前:\n");
	for(int i=1;i<=len;i++)
	{
		printf("%d ",array[i]);
	}	
	merge_sort(array,1,len);
	printf("\n排序后结果为:\n");
	for(int i=1;i<=len;i++)
	{
		printf("%d ",array[i]);
	}
	finish=clock();
	printf("\nRunning Time:%d s",(finish-start)/CLOCKS_PER_SEC);
	return 0;
} 
void merge(int array[],int p,int q,int r)
{
	int n1=q-p+1,n2=r-q,i,j,k;
	int L[n1+2],R[n2+2];
	L[0]=-1;
	for(i=1;i<=n1;i++)
	{
		L[i]=array[p+i-1];
	}
	L[n1+1]=INF;
	R[0]=-1;
	for(j=1;j<=n2;j++)
	{
		R[j]=array[q+j]; 
	}
	R[n2+1]=INF;
	i=1;j=1;
	for(k=p;k<=r;k++)
	{
		if(L[i]>=R[j])
		{
			array[k]=L[i];
			i++;
		}
		else
		{
			array[k]=R[j];
			j++;
		}
	}
}

void merge_sort(int array[],int p,int r)
{
	if(p<r)
	{
		int q=(p+r)/2;
		merge_sort(array,p,q);
		merge_sort(array,q+1,r);
		merge(array,p,q,r);		
	}
	else 
	{
		return ;
	}
}

从小到大的排序:

//归并排序 
#include "stdio.h"
#include "math.h"
#include "time.h"
#include "stdlib.h"
#define MAXSIZE 1000
#define INF 100000
int array[MAXSIZE];
int start,finish;
int main ()
{
	start=clock();
	int len;
	void merge_sort(int array[],int p,int r);
	void merge(int array[],int p,int q,int r);
	printf("输入数组元素个数:\n"); 
	scanf("%d",&len);
	for(int i=1;i<=len;i++)
	{
		array[i]=(rand()%10000);
	}
	printf("排序前:\n");
	for(int i=1;i<=len;i++)
	{
		printf("%d ",array[i]);
	}	
	merge_sort(array,1,len);
	printf("\n排序后结果为:\n");
	for(int i=1;i<=len;i++)
	{
		printf("%d ",array[i]);
	}
	finish=clock();
	printf("\nRunning Time:%d s",(finish-start)/CLOCKS_PER_SEC);
	return 0;
} 
void merge(int array[],int p,int q,int r)
{
	int n1=q-p+1,n2=r-q,i,j,k;
	int L[n1+2],R[n2+2];
	L[0]=-1;
	for(i=1;i<=n1;i++)
	{
		L[i]=array[p+i-1];
	}
	L[n1+1]=INF;
	R[0]=-1;
	for(j=1;j<=n2;j++)
	{
		R[j]=array[q+j]; 
	}
	R[n2+1]=INF;
	i=1;j=1;
	for(k=p;k<=r;k++)
	{
		if(L[i]<=R[j])
		{
			array[k]=L[i];
			i++;
		}
		else
		{
			array[k]=R[j];
			j++;
		}
	}
}

void merge_sort(int array[],int p,int r)
{
	if(p<r)
	{
		int q=(p+r)/2;
		merge_sort(array,p,q);
		merge_sort(array,q+1,r);
		merge(array,p,q,r);		
	}
	else 
	{
		return ;
	}
}

猜你喜欢

转载自blog.csdn.net/CSDN___CSDN/article/details/83471804