归并的递归和非递归排序

1.归并排序递归

从中间将一整个数组分成两个数组,假设这两个数组已经完成了排序,那么设立一个新的数组,取两个数组各自第一个数据进行比较,那个数组的数据小就放入这个新建的数组,然后再重新在这个数组取数,再和另外一个数组原来取的数进行比较,那个小那个就放入这个新建的数组,直到有一个数组的数被取完,那么另外一个数组的全部数据都将依次放入新建的组,再将新建的数组的数据mencpy到原数组中就完成了排序,

那么要怎么使两边的数组都是有序的呢???

请看VCR

通过以上的递归方式实现排序,当递归的数只剩两个那么这两边就是有序的那么这两边就能进行比较排序,进行完比较排序了之后就返回这个数组,然后其它的数组也一样返回,所有返回完毕便实现了数组的排序。

代码实现如下

void swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
void _MergeSort(int* a,int* temp,int left,int right)
{
	if (left >= right)
	{
		return;
	}
	int mid = (right + left) / 2;
	int begin1 = left;
	int begin2 = mid+1;
	int end1 = mid;
	int end2 = right;

	_MergeSort(a, temp, begin1, end1);
	_MergeSort(a, temp, begin2, end2);
	int i = begin1;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1]<a[begin2])
		{
			temp[i++] = a[begin1++];
		}
		else
		{
			temp[i++] = a[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		temp[i++] = a[begin1++];
	}
	while (begin2<=end2)
	{
		temp[i++] = a[begin2++];
	}
	memcpy(a + left, temp + left, sizeof(int) * (right - left + 1));
}
void MergeSort(int* a, int n)
{
	int left = 0, right = n - 1;
	int* temp = (int*)malloc(sizeof(n));
	
	_MergeSort(a, temp, left, right);
}

 2.归并排序非递归

归并排序非递归就是先将数组两个两个进行排序,再四个四个进行,再八个八个进行。直到数组被分为两组排序那么就结束。

代码实现如下 

void MergeSortNonR(int* a, int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc");
		return;
	}
	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i = i + gap * 2)
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			if (end1 >= n-1)
			{
				break;
			}
			if (end2 >= n-1)
			{
				end2 = n - 1;
			}
			int j = begin1;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] < a[begin2])
				{
					temp[j++] = a[begin1++];
				}
				else
				{
					temp[j++] = a[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				temp[j++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				temp[j++] = a[begin2++];
			}
			memcpy(a + i, temp + i, sizeof(int) * (end2 - i + 1));//没有搞清楚begin1和i,begin1会变

		}
		gap = gap * 2;
	}
}

但是排序时要注意,因为访问位置是2的倍数增加,当数组个数不是二的倍数时就会造成越界访问,所以在上述代码中增加了如下代码。 

			if (end1 >= n-1)
			{
				break;
			}
			if (end2 >= n-1)
			{
				end2 = n - 1;
			}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值