二路归并排序实现

这篇博客详细介绍了二路归并排序的算法思想,它基于归并操作,通过不断合并有序序列来构建新的有序序列。内容涵盖从基本的归并算法原理到C语言的代码实现,适用于理解及应用数据结构和排序算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、归并算法思想

归并算法是建立在归并操作的基础上的。归并操作是指将两个或者多个以上的有序序列合并成一个新的序列,得到的新序列仍然有序。假设待排序序列大小为n,则初始状态下待排序序列有n个有序的子序列,其中每个子序列的大小为1,经过一次“两两归并”后,待排序序列将包含多个有序的大小为2的子序列。。。以此类推,直到整个序列有序。

算法演示


二、代码实现

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DATA_SIZE	10

int*  init_data(int size);
void print_data(int* pdata, int size);
void swap(int* pdata, int i, int j);
int  max(int* pdata, int i, int j);
void do_sort(int *pdata, int size);
void merge(int *pdata, int idx1, int len1, int idx2, int len2);
void free_data(int *pdata);

int main()
{	
	int *pdata = init_data(DATA_SIZE);
	
	if (NULL == pdata)
	{
		return -1;
	}

	puts("Before sort:");	
	print_data(pdata, DATA_SIZE);

	do_sort(pdata, DATA_SIZE);

	puts("After sort:");
	print_data(pdata, DATA_SIZE);

	free_data(pdata);
	return 0;
}

int*  init_data(int size)
{
	int *pdata = (int*)malloc(size*sizeof(int));
	if (NULL == pdata)
	{
		return NULL;
	}

	int i;
	
	srand(time(NULL));

	for (i = 0 ; i < size ; ++i)
	{
		pdata[i] = rand()%100;	
	}

	return pdata;
}
void print_data(int* pdata, int size)
{
	int i;

	for (i = 0 ; i < size ; ++i)
	{
		printf("%4d", pdata[i]);
	}

	printf("\n");
}

void swap(int* pdata, int i, int j)
{
	int tmp;

	tmp = pdata[i];
	pdata[i] = pdata[j];
	pdata[j] = tmp;
}

int  max(int* pdata, int i, int j)
{
	return pdata[i] >= pdata[j] ? i : j;
}

void do_sort(int *pdata, int size)
{
	int subseqlen = 1;
	int subseqnum = size;

	while (subseqlen < size)
	{
		int mergetime = subseqnum / 2;
		int i;

		for (i = 0 ; i < mergetime ; ++i)
		{
			int startidx1 = i*2*subseqlen;
			int len1 = subseqlen;
			int startidx2 = startidx1 + subseqlen;
			int len2 = (size -  startidx1 - len1) < subseqlen ? (size - startidx1 - len1) : subseqlen;

			merge(pdata, startidx1, len1, startidx2, len2);

		}
		
		subseqlen *= 2;
		subseqnum = (size + subseqlen - 1) / subseqlen;
	}
}

void merge(int *pdata, int startidx1, int len1, int startidx2, int len2)
{
	int *tmp;

	tmp = (int*)malloc((len1+len2)*sizeof(int));
	if (NULL ==  tmp)
	{
		return;
	}

	int idx1 = startidx1;
	int idx2 = startidx2;
	int tmpidx = 0;
	
	while ((idx1 - startidx1) < len1 && (idx2 - startidx2) < len2)
	{
		if (pdata[idx1] < pdata[idx2])
		{
			tmp[tmpidx] = pdata[idx1];
			idx1++;
		}
		else 
		{
			tmp[tmpidx] = pdata[idx2];
			idx2++;
		}
		tmpidx++;
	}
	
	if ((idx1 - startidx1) < len1)
	{
		while ((idx1 - startidx1) < len1)
		{
			tmp[tmpidx] = pdata[idx1];
			idx1++;
			tmpidx++;
		}
	}
	else if ((idx2 - startidx2) < len2)
	{
	 	while ((idx2 - startidx2) < len2)
	        {
			tmp[tmpidx] = pdata[idx2];
			idx2++;
			tmpidx++;
		}
	}
	int j;
	
	for (j = 0; j < len1+len2 ; ++j)
	{
		pdata[startidx1+j] = tmp[j];
	}

	free(tmp);
}
void free_data(int *pdata)
{
	free(pdata);
	pdata = NULL;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值