C++排序算法——归并排序

归并排序C++

归并排序从小到大排序:首先让数组中的每一个数单独成为长度为1的区间,
然后两两一组有序合并,得到长度为2的有序区间,依次进行,直到合成整个区间。


#include <iostream>
using namespace std;

//4 归并排序
/*
归并排序从小到大排序:首先让数组中的每一个数单独成为长度为1的区间,
然后两两一组有序合并,得到长度为2的有序区间,依次进行,直到合成整个区间。
*/
//4.3 核心代码(函数)
//1 递归实现
//函数声明
void MergeSort(int array[]);
void MSort(int array[], int Result[], int start, int end);
void Merge(int array[], int Ans[], int start, int midd, int endd);   //将两个排序序列排序   从小到大排序

//函数实现
void MergeSort(int array[])
{
	MSort(array, array, 0, 9);
}

void Merge(int array[],int Ans[], int start, int midd, int endd)   //将两个排序序列排序   从小到大排序
{
	int i = start;     //记录前半段的下标
	int j ;            //记录后半段的下标
	int k;             //记录结果Ans的下标
	for ( j = midd + 1, k = i; i <= midd && j <= endd; k++)
	{
		if (array[i] > array[j])
		{
			Ans[k] = array[j];
			j++;
		}
		else
		{
			Ans[k] = array[i];
			i++;
		}

	}

	if (i <= midd)   //
	{
		for (; i <= midd; i++,k++)
		{
			Ans[k] = array[i];
		}
	}

	if (j <= endd)   //
	{
		for (; j <= endd; j++, k++)
		{
			Ans[k] = array[j];
		}
	}
}
void MSort(int array[], int Result[], int start, int end)
{
	int Tmp[1000];
	if (start == end)
		Result[start] = array[start];
	else 
	{
		int mid = (start+end) / 2;        //中间点的位置,从中间点将数组分成两部分
		MSort(array, Tmp, start, mid);    //左半部分排序
		MSort(array, Tmp, mid + 1, end);   //右半部分排序
		Merge(Tmp, Result,start, mid, end);   //合并
	}
}


//2:迭代实现
void MergeSortIter(int k[], int n)
{
	int i, next, left_min, left_max, right_min, right_max;
	//动态申请一个与原来数组一样大小的空间用来存储
	int *temp = (int *)malloc(n * sizeof(int));
	//逐级上升,第一次比较2个,第二次比较4个,第三次比较8个。。。  
	for (i = 1; i<n; i *= 2)
	{
		//每次都从0开始,数组的头元素开始  
		for (left_min = 0; left_min<n - i; left_min = right_max)
		{
			right_min = left_max = left_min + i;
			right_max = left_max + i;
			//右边的下标最大值只能为n  
			if (right_max>n)
			{
				right_max = n;
			}
			//next是用来标志temp数组下标的,由于每次数据都有返回到K,  
			//故每次开始得重新置零  
			next = 0;
			//如果左边的数据还没达到分割线且右边的数组没到达分割线,开始循环  
			while (left_min<left_max&&right_min<right_max)
			{
				if (k[left_min] < k[right_min])
				{
					temp[next++] = k[left_min++];
				}
				else
				{
					temp[next++] = k[right_min++];
				}
			}
			//上面循环结束的条件有两个,如果是左边的游标尚未到达,那么需要把  
			//数组接回去,可能会有疑问,那如果右边的没到达呢,其实模拟一下就可以  
			//知道,如果右边没到达,那么说明右边的数据比较大,这时也就不用移动位置了  

			while (left_min < left_max)
			{
				//如果left_min小于left_max,说明现在左边的数据比较大  
				//直接把它们接到数组的min之前就行  
				k[--right_min] = k[--left_max];
			}
			while (next>0)
			{
				//把排好序的那部分数组返回该k  
				k[--right_min] = temp[--next];
			}
		}
	}
}
//非递归的方法,避免了递归时深度为log2N的栈空间,
//空间只是用到归并临时申请的跟原来数组一样大小的空间,并且在时间性能上也有一定的提升,
//因此,使用归并排序是,尽量考虑用非递归的方法。


int main(  )
{
	int array[10] = { 3,5,4,6,9,8,7,1,2,0};
	
	int len = sizeof(array) / sizeof(int);

	for (int i = 0; i < len; i++)
		cout << array[i] << " ";
	cout << endl;
	cout << "*************************"<< endl;

	
	//insertSort(array,len);  //插入排序

	MergeSort(array);      //归并排序

	//adjust_quicksort(array,10);  //快速排序


	for (int i = 0; i < len; i++)
		cout << array[i] << " ";
	cout << endl;
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhenaoxi1077/article/details/82762423