常见的排序——归并排序

归并排序基本思想:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段有序。开辟一个数组用来存放,我们要排的数据。将数组分为两区间,用递归进行对这两个区间数组进行排序,然后去合并它们(合并和链表的合并一样)直到它们有序为止。

void Merger(int array[], int left, int mid, int right, int *exter)
{
	int left_index = left;
	int right_index = mid;
	int exter_index = 0;
	//进行两个数组的合成
	while (left_index<mid&&right_index<right)
	{
		if (array[left_index] <= array[right_index]){
			exter[exter_index] = array[left_index];
			left_index++;
		}
		else{
			exter[exter_index] = array[right_index];
			right_index++;
		}
		exter_index++;
	}
	//走到这里说明一个数组已经排完了
	while (left_index < mid){
		exter[exter_index++] = array[left_index++];
	}
	while (right_index < right){
		exter[exter_index++] = array[right_index++];
	}
	//将新开辟的数组里面的值传到原来数组中去
	int size = right - left;
	for (int i = 0; i < size; i++){
		//注意这里原来数组里面要从left开始,因为传值的时候原来数组有可能已经有值了
		array[left + i] = exter[i];
	}
}
void _MergerSort(int array[], int left, int right, int *exter)
{
	//数组要排序的空间里面有一个或没有值时说明数组有序
	if (left + 1 == right){
		return;
	}
	if (left > right){
		return;
	}
	int mid = (right - left) / 2 + left;
	//进行递归将数组分成小块进行排序
	_MergerSort(array, left, mid, exter);
	_MergerSort(array, mid, right, exter);
	//将两个数组进行合并
	Merger(array, left, mid, right, exter);
}
void MergerSort(int array[], int size)
{
	//开辟空间
	int *exter = (int *)malloc(sizeof(int)*size);
	_MergerSort(array, 0, size, exter);
	free(exter);
}

归并排序的特性总结:时间复杂度O(n*logn),空间复杂度O(n),是一个稳定的排序。归并的缺点在于需要O(n)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题(4g内存,100g硬盘,然后每次从硬盘上面取2g下来进行排序)。

猜你喜欢

转载自blog.csdn.net/weixin_43198968/article/details/88559632