算法竞赛入门经典:第八章 高效算法设计 8.2归并排序

/*
归并排序:
1 注意每次划分时候使用一个辅助数组

输入:
8
1 9 6 3 4 7 9 0
输出:
0 1 3 4 6 7 9 9
*/

/*
关键:
1 void mergeSort(int* iArr,int low,int high,int* iTempArr)//注意,high是取不到的,因此传入的实参为数组长度n
2 if(high - low > 1)//递归出口,所剩元素大于1,只有一个元素没有必要排序,递归入口一般是:low < high,所剩元素大于1个
3 int mid = low + (high - low) / 2;//分治第一步,划分,技巧,向中间节点靠拢
4 int l = low,m = mid,i = low;//l,m分别作为排序时的下标,而i是作为临时数组的下标
5 mergeSort(iArr,low,mid,iTempArr);//分治第二部,递归求解
6 if(m >= high || (l < mid && iArr[l] <= iArr[m]))//如果右边已经排好 或者 左边没排好(易漏,如果左边已经排好,就会数组越界) 并且左边小于等于右边
7 for(int j = low ; j < high; j++)//注意,这里由于high取不到,因此用j<high
*/

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

#define MAXSIZE 1024


void mergeSort(int* iArr,int low,int high,int* iTempArr)//注意,high是取不到的,因此传入的实参为数组长度n
{
	if(high - low > 1)//递归入口,所剩元素大于1,只有一个元素没有必要排序
	{
		int mid = low + (high - low) / 2;//分治第一步,划分,技巧,向中间节点靠拢
		int l = low,m = mid,i = low;//l,m分别作为排序时的下标,而i是作为临时数组的下标
		mergeSort(iArr,low,mid,iTempArr);//分治第二部,递归求解
		mergeSort(iArr,mid,high,iTempArr);
		while(l < mid || m < high)
		{
			if(m >= high || (l < mid && iArr[l] <= iArr[m]))//如果右边已经排好 或者 左边没排好(易漏,如果左边已经排好,就会数组越界) 并且左边小于等于右边
			{
				iTempArr[i++] = iArr[l++];
			}
			else
			{
				iTempArr[i++] = iArr[m++];
			}
		}
		for(int j = low ; j < high; j++)//注意,这里由于high取不到,因此用j<high
		{
			iArr[j] = iTempArr[j];
		}
	}
}

void print(int* iArr,int n)
{
	for(int i = 0 ; i < n; i++)
	{
		if(i)
		{
			printf(" %d",iArr[i]);
		}
		else
		{
			printf("%d",iArr[i]);
		}
	}
	printf("\n");
}

void process()
{
	int n;
	while(EOF != scanf("%d",&n))
	{
		int iArr[MAXSIZE];
		int iTempArr[MAXSIZE];
		for(int i = 0 ; i < n ; i++)
		{
			scanf("%d",&iArr[i]);
		}
		mergeSort(iArr,0,n,iTempArr);
		print(iArr,n);
	}
}

int main(int argc,char* argv[])
{
	process();
	system("pause");
	return 0;
}

你可能感兴趣的:(归并排序)