数据结构-排序-归并排序

在这里插入图片描述

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

// 16 17 13 10 9 15 3 2 5 8 12 1 11 4 6 14

void Merge(int * arr1, int * arr2, int head, int middle, int tail)
{
	int t = middle+1;
	//int k=0;//arr2的坐标 此处的k不能为0,为0的话会覆盖之前已经比较过的
	int k = head;
	for (; head <=middle&&t<=tail;)
	{
		if (arr1[head] > arr1[t])
		{
			arr2[k++] = arr1[t++];
		}
		else
		{
			arr2[k++] = arr1[head++];
		}
	}

	//判断剩下的加到arr2中
	if (head<=middle)
		for (; head <= middle; )
			arr2[k++] = arr1[head++];
	if (t <= tail)
		for (; t <= tail;)
			arr2[k++] = arr1[t++];

}

void Msort(int * arr1, int * arr2, int head,int tail)//函数功能:给两个数组,进行合并并排序
{
	int m;//中间
	int arrtemp[16] = {0};
	if (head == tail)//只有一个数的情况
	{
		arr2[head] = arr1[head];
	}
	else
	{
		m = (head + tail) / 2;
		Msort(arr1, arrtemp, head, m );//此处不能从m-1开始
		Msort(arr1, arrtemp, m+1, tail);
		Merge(arrtemp, arr2, head, m, tail);//如果Merge 函数里面的k初始值为0,则arrtemp永远只有两个的比较

		//for (int i = 0; i < 16; i++)
		//{
		//	printf(" %d", arrtemp[i]);
		//}
		//printf("\n");
	}
}


void main()
{
	int arr[16] = { 16,17,13,10,9,15,3,2,5,8,12,1,11,4,6,14 };

	//Merge(arr1, arr2, 0,0,0);

	Msort(arr, arr, 0, 15);
	for (int i = 0; i < 16; i++)
	{
		printf(" %d", arr[i]);
	}
	system("pause");
}

并归排序不用递归

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

// 16 17 13 10 9 15 3 2 5 8 12 1 11 4 6 14
#define SIZE 32

void Merge(int * arr1, int * arr2, int head, int middle, int tail)
{
	int t = middle+1;
	int k = head;
	//int k=0;//arr2的坐标 此处的k不能为0,为0的话会覆盖之前已经比较过的
	for (; head <= middle&&t <= tail;)
	{
		if (arr1[head] > arr1[t])
		{
			arr2[k++] = arr1[t++];
		}
		else
		{
			arr2[k++] = arr1[head++];
		}
	}

	//判断剩下的加到arr2中
	if (head <= middle)
		for (; head <= middle; )
			arr2[k++] = arr1[head++];
	if (t <= tail)
		for (; t <= tail;)
			arr2[k++] = arr1[t++];
}

void MsortA(int * arr1, int head, int tail)//不采用递归的方式
{
	int i = 2;
	int arrtemp[SIZE] = { 0 };
	
	while (i<=tail*2) 
	{
		int j = 0;
		while (j <= tail)
		{
			int chazhi = 0;

			if (j+i > tail+1)//计算j循环到最后少几个数,一般都是2,4,8,16,32合并,而实际的比较数据没有这么凑巧的
			{
				chazhi = i-(tail+1)%i;
			}
			
			int m;
			//m = (j + (i-chazhi) / 2) - 1;这里i不能减去插值后再除以2,例如10个数的数组,最有的合并还是应该merge(arr,arrtemp,0,7,9)
			m = (j + (i) / 2)-1;

			Merge(arr1, arrtemp, j, m, j+i-1-chazhi);

			for (int k=0; k <= j+i-1; k++)
				arr1[k] = arrtemp[k];
				j = j + i;
		}
		i*=2;
	} 
}


void main()
{
	int arr[SIZE] = { 16 ,7, 13 ,10 ,9 ,15 ,2, 5,8,10,34,18,17,14,1,16,55};
	int arr2[SIZE] = { 0 };

	//Merge(arr1, arr2, 0,0,0);

	MsortA(arr,0, 16);

	for (int i = 0; i < 17; i++)
	{
		printf(" %d", arr[i]);
	}

	system("pause");	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值