算法导论练手系列之归并排序

/*************************************************************************
    > File Name: merge-sort.c
    > Author: JayTan
    > Mail: jaytanfly@gmail.com 
    > Created Time: 2018年05月12日 星期六 09时13分18秒
 ************************************************************************/


/**MERGE的伪代码,选自算法导论 Page17
 * 功能:A是一个数组,p,q和r是数组下标,满足p=<q<r。该过程假设子数组A[p...q]和A[q+1 ...r]都已排好序。它合并这两个子数组形成单一的已排好序的子数组并代替当前的子数组A[p ..r]
 *
 * MERGE(A, p, q, r)
 *	n1 = q - p +1
 *	n2 = r -q
 *	let L[1...n1+1] and R[1...n2+1] be new arrays
 *	for i = 1 to n1
 *		L[i] = A[p+i-1]
 *	for j = 1 to n2
 *		R[j] = A[q+j]
 *
 *	L[n1 + 1] = $
 *	R[n2 + 1] = $
 *
 *	i = 1
 *	j = 1
 *	for k = p to r
 *		if L[i] =< R[j]
 *			A[k] = L[i]
 *			i++;
 *		else 
 *			A[k] = R[j]
 *			j = j+1
 *
 *然后将MERGE作为归并排序算法中的一个子程序来用。下面的过程MERGE-SORT(A, p, r)排序子数组A[p..r]中的元素。若 p => r,则该子数组最多有一个元素,所以已经排好序。否则,分解步骤简单地计算一个下标q,将A[p..r]分成两个子数组A[p..q]和A[q+1..r],前者包含[n/2]个元素,后者包括[n/2]个元素。
 * 
 * MERGE-SORT(A, p, r)
 * if p<r
 *	q = [(p+r)/2]
 *	MERGE-SORT(A, p, q)
 *	MERGE-SORT(A, q+1, r)
 *	MERGE(A, p, q, r)
 *
 * */

#include <stdio.h>
#include <malloc.h>

void merge(int *array,int p, int q, int r);

void merge_sort(int *array,int p,int r);
int main(int argc, char** argv)
{
	int i = 0;
#if 0
	int A[] = {2,6,8,2,4,5,7,1,2,3,6};//11
	merge(A,3,6,10);
#endif

	int B[] = {3,2,54,45,12,31,36,8,6,3,87,32,62,79,26,63};
	//int B[] = {4,3,2,1};
	//int B[] = {2,1};
	printf("B before sort is:");
	for(i=0;i<sizeof(B)/sizeof(int);i++)
		printf("%d ",B[i]);
	printf("\n");

	merge_sort(B,0,sizeof(B)/sizeof(int)-1);

	printf("B after sort is:");
	for(i=0;i<sizeof(B)/sizeof(int);i++)
		printf("%d ",B[i]);
	printf("\n");

}


void merge_sort(int *array,int p,int r)
{
	int q = 0;
	if(p < r)
	{
		q = (p+r)/2;
		merge_sort(array,p,q);
		merge_sort(array,q+1,r);
		merge(array, p, q, r);
	}
}

void merge(int *array,int p, int q, int r)
{
	int n1 = q - p + 1;
	int n2 = r - q;
	int *pL = malloc((n1+1)*sizeof(int));
	int i = 0,j=0;
	int k=0;
	
	printf("array before sort is:");
	for(k=p;k<=r;k++)	
		printf("%d ",array[k]);
	printf("\n");

	for(i=0;i<n1;i++)
		pL[i] = array[p+i];
	pL[n1] = -1;
	
	for(i=0;i<n1+1;i++)
		printf("%d ",pL[i]);
	printf("\n");

	int *pR = malloc((n2+1)*sizeof(int));
	for(i=0;i<n2;i++)
		pR[i] = array[i+q+1];
	pR[n2] = -1;

	for(i=0;i<n2+1;i++)
		printf("%d ",pR[i]);
	printf("\n");

	i = 0;
	k = 0;
	
	for(k = p;k<=r;k++)
	{

		if((pL[i] <= pR[j] && pL[i] > 0)|| (pR[j] < 0) )
		{
			array[k] = pL[i];
			i++;
		}
		else
		{
			array[k] = pR[j];
			j++;
		}
	}

	printf("array after sort is:");
	for(k=p;k<=r;k++)	
		printf("%d ",array[k]);
	printf("\n");

	free(pL);
	pL = NULL;
	free(pR);
	pR = NULL;

}


版权声明:本文为博主原创文章,未经博主允许不得转载。原文链接:https://blog.youkuaiyun.com/ta_tan
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值