C语言 归并排序算法

归并排序算法完全遵循分治模式。直观上其操作如下:

分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。

解决:使用归并排序递归地排序两个子序列。

合并:合并两个已排列的子序列以产生已排序的答案。

随着算法自底向上地推进,待合并的已排好序的各序列长度不断增加,最后全部合并成等于原序列长度的一个新的已排列的序列。

// 归并排序
// low, mid, high 均为数组下标

#include 
#include 

#define length(a) ((sizeof(a))/(sizeof(a[0])))

void printArray(int* a, int length)
{
	int temp;
	for (temp = 0; temp < length; temp++)
	{
		printf("%d ", a[temp]);
	}
	printf("\n");
}

void mergeSort(int* a, int low, int high);
void merge(int* a, int low, int mid, int high);

int main(void)
{
	int a[] = { 5,2,4,6,1,3,6 };
	printf("排序前:\n");
	printArray(a, length(a));
	mergeSort(a, 0, length(a) - 1);
	printf("排序后:\n");
	printArray(a, length(a));

	return 0;
}
void mergeSort(int* a, int low, int high)
{
	int mid;
	if (low < high)
	{
		mid = (low + high) / 2;
		mergeSort(a, low, mid);
		mergeSort(a, mid + 1, high);
		merge(a, low, mid, high);
	}
}
void merge(int* a, int low, int mid, int high)
{
	int i, j, k;

	//左半数组和右半数组的长度
	int n1 = mid - low + 1;
	int n2 = high - mid;

	//为左半数组和右半数组开辟空间,预留多一个元素的位置存放哨兵
	int* L = (int*)malloc(sizeof(int) * (n1 + 1));
	int* R = (int*)malloc(sizeof(int) * (n2 + 1));

	//将原数组中的元素分别放入左右数组
	for (i = 0; i < n1; i++)
		L[i] = a[low + i];
	for (j = 0; j < n2; j++)
		R[j] = a[mid + j + 1];

	//在左半数组和右半数组的最后放置哨兵,这样做无需检查是否有数组为空
	L[i] = 2147483647;
	R[j] = 2147483647;

	//将左右数组中较小的数逐渐放回原数组
	i = j = 0;
	for (k = low; k <= high; k++)
	{
		if (L[i] <= R[j])
			a[k] = L[i++];
		else
			a[k] = R[j++];
	}

	free(L);
	free(R);
}

你可能感兴趣的:(算法,c语言,排序算法,算法)