栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

归并排序(一)——递归排序

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

归并排序(一)——递归排序

归并的思想和前面说的快排比较类似,

 

快排是先通过单趟排序,产生一个分界点,然后分界点的两侧重新开始单趟排序

归并是直接将以数组的中心位置作为分界点,不断取中间位置,分成两个小区间,直到无法分解

核心思路:先分解左半部分,然后排序

                  再分解右半部分,然后排序

一、算法基本思路 1、先分解

将数组分解至无法继续往下分解,如下

2、再排序

排序时,从最底层开始排序

(1)9 可以看作一个数组arr1 ,3  可以看作一个数组arr2  

(2)3比9小,3先放入临时数组,由于arr2数组结束了,所以直接把9放到临时数组的末尾

    

(3)然后把tmp数组的值去替换 原数组中对应位置的值

​​​​​​​           ​​​​​​​

   3、整体过程

上面的数组更新过程可能有点抽象

先调整 9  3(倒数第一层)——会变成3 9

               

                 ​​​​​​​                                            

            

 后续过程

后续是按照红色、蓝色、橙色的区间排序,左边就排序结束了

然后再对右边开始排序,同样也是从底层向上排序

二、递归排序代码实现 1、单层排序

void SingleLevelSort(int* a,int left,int right)
{
    //第一个区间的起始位置
    int begin1 = left, end1 = mid;
    //第二个区间的起始位置
	int begin2 = mid + 1, end2 = right;
	//tmp 用于临时存放排列好的数据
	int size = right - left + 1;
	int* tmp = new int[size];

	int p = 0;
	while (begin1 <= end1 && begin2 <= end2)
	{
        //begin2小,则begin2放入临时数组,begin2向后移动一位
		if (a[begin1]>a[begin2])
		{
			tmp[p++] = a[begin2++];
		}
		else
		{
			tmp[p++] = a[begin1++];
		}
	}

	//将还有剩余的区间,拼接到tmp的后面
	while (begin1 <= end1)
	{
		tmp[p++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		tmp[p++] = a[begin2++];
	}

	//当前区间的排序结束,将tmp中的数据更新到原数组
	for (size_t i = 0; i < size; i++)
	{
        //注意 a 存放数据的范围是 [left,right]
        // tmp存放数据的范围是  [0,size-1]
		a[left+i] = tmp[i];
	}

	delete[] tmp;
	tmp = nullptr;
}
2、递归排序

void MergeSort(int* a,int left,int right) {
    //到达底端的只剩一个数的时候,无法分解,返回上一级
	if (left>=right)
	{
		return;
	}

    //取排序的中间位置,分成两个小区间
	int mid = (left + right) / 2;
	//左区间,向左分解
	MergeSort(a, left, mid);
	//右区间,向右分解
	MergeSort(a, mid + 1, right);

    //只有分解到达底端的时候,才会开始调用这个函数,然后一步步向上排序
    SingleLevelSort(a,left,right);
}
三、代码测试
int main()
{
	int arr[] = { 9,3,4,6,2,5,1,7,8};
	MergeSort(arr, 0, sizeof(arr) / sizeof(arr[0])-1);

	for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	return 0;
}

 

四、时间复杂度

从第二部分的向下分解可以看出,逻辑结构类似于二叉树

====》时间复杂度:O(N*log N)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767934.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号