排序算法——归并排序

(一)递归调用(函数递归调用),自顶向下

/**
 * Merge_Sort: 归并排序的递归实现
 * 注:算法导论上给出的合并排序算法
 * 递归过程是将待排序集合一分为二,
 * 直至排序集合就剩下一个元素为止,然后不断的合并两个排好序的数组
 * T(n) = O(nlgn)
 **/

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

void merge(int a[], int start, int mid, int end)
{
	int i = 0, j = 0, k = start;
	int n1 = mid - start + 1;
	int n2 = end - mid;
	int *first = (int *)malloc(sizeof(int)*n1);
	int *last = (int *)malloc(sizeof(int)*n2);
	for (int m = 0; m < n1; m++)
		first[m] = a[start + m];
	for (int n = 0; n < n2; n++)
		last[n] = a[mid + n + 1];
	while (i < n1&&j < n2)
	{
		if (first[i] < last[j])
			a[k++] = first[i++];
		else
			a[k++] = last[j++];
	}
	if (i < n1)a[k++] = first[i++];
	if (j < n2)a[k++] = last[j++];
}

void merge_sort(int a[], int start, int end)
{
	int mid ;
	if (start < end)
	{
		mid = (start + end) / 2;
		/*分而治之,先分解,在归并*/
		merge_sort(a, start, mid);//递归划分原数据左半边
		merge_sort(a, mid + 1, end);//递归划分原数据右半边
		merge(a, start, mid, end);//归并
	}
}

int main()
{
	int a[8] = { 1, 2, 4, 5, 3, 9, 7, 8 };
	merge_sort(a, 0, 7);
	//merge(a, 0, 3, 7);
	for (int i = 0; i < 8; i++)
	{
		printf("%d  ", a[i]);
	}
	return 0;
}

(二)非递归(迭代,循环展开)--自底向上

/**
 * merge_sort: 非递归实现 --迭代
 * 非递归思想: 将数组中的相邻元素两两配对。用merge函数将他们排序,
 * 构成n/2组长度为2的排序好的子数组段,然后再将他们排序成长度为4的子数组段,
 * 如此继续下去,直至整个数组排好序。
**/

#include <stdio.h>
#include <stdlib.h>
void merge_sort(int list[], int length)
{
	int step, left_min, left_max, right_min, right_max, next;
	int *tmp = (int*)malloc(sizeof(int) * length);

	if (tmp == NULL)
	{
		fputs("Error: out of memory\n", stderr);
		abort();
	}

	for (step = 1; step < length; step *= 2) // step为步长,1,2,4,8……
	{
		for (left_min = 0; left_min < length - step; left_min = right_max)
		{
			right_min = left_max = left_min + step;
			right_max = left_max + step;

			if (right_max > length)
				right_max = length;
			next = 0;
			while (left_min < left_max && right_min < right_max)
				tmp[next++] = list[left_min] > list[right_min] ? list[right_min++] : list[left_min++];

			while (left_min < left_max)
				list[--right_min] = list[--left_max];

			while (next > 0)
				list[--right_min] = tmp[--next];
		}
	}

	free(tmp);
}


int main()
{
	int a[8] = { 1, 2, 4, 5, 3, 9, 7, 8 };
	merge_sort(a, 8);
	for (int i = 0; i < 8; i++)
	{
		printf("%d  ", a[i]);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值