高级排序算法之归并排序

在自己摸爬滚打前行或是后退的时候,总会出现很多的惊喜或意外

楼主大三狗,前些天异想天开想面试青少年编程老师一职

没想到对面坐的是科大讯飞十年辞职创业的高级攻城狮。。。

很尬,未果。我说了近况,并没有潜心研究算法云云,一直在入门机器学习,深度学习

他说本科生在没有能力的情况下不要研究这些……最好学学算法,以后出来找工作肯定是不成问题的。。

前言背景有点长,下面正式开始

归并排序是一种高效率的算法,时间复杂度只有O(nlogn)

它的核心思想是分治策略

如下图,分是将其二分至不可再分

分完需要再合,合的方法是如下

俩俩互相比较大小,做好排序,这里的已经合并的还剩下最后一步。

到了思想关键的地方了,如何给这些进行排序呢?

需要创建一个数组,来保存原数组信息,在拿拷贝的数组进行对原数组进行修改,即排序

需要建立三个游标,如下:

<ignore_js_op>

下面一行为拷贝数组,将两端进行比较,设左端为起始为l,末端为mid;右端起始即为mid+1,末端为r

设遍历游标为i,j

取第一个元素比较做范例,若arr[l] < arr[mid+1]  则将原数组a[k] = arr[l]值即可

所以大致分类如下:

1.如果 i > mid,则说明左端遍历已结束;

2.如果j > r,则说明右端遍历已结束;

3.如果上述两者都不满足,则说明两端遍历都没有结束,则比较arr与arr[j]的关系即可


3.1. 若arr > arr[j] ,则原数组a[k] = arr[j] ,此时 j ++ ,k++,j,k自增,游标向右移;

3.2 .若arr < arr[j] ,则原数组a[k] = arr , 此时 i ++ ,k ++,i,k自增,游标向右移。

不明白如何分治,如下博客:https://www.cnblogs.com/wyongbo/p/Devide.html
贴出代码,困于递归很久,毕竟接触的少

如果有对递归不熟悉的可以在函数里多使用printf函数来进行输出,探测函数的走向

//归并排序算法
template<typename T>
void __Merge(T arr[], int l, int mid, int r)
{
	printf("\n排序函数入口 l = %d, mid = %d, r = %d \n", l, mid, r);
	T* aux = new T[r - l + 1];		//创建数组指针,新版可以直接使用变量创建,如下一行代码
	//T aux[r - l + 1];				//创建一个数组
	for (int i = l; i <= r; i++)	//拷贝数组
	{
		aux[i - l] = arr[i];
		printf("拷贝数组a[%d] = arr[%d] = %d \n", i - l, i, arr[i]);
	}

	int i = l, j = mid + 1;			//将数组分成两部分进行比较
	for (int k = l; k <= r; k++)
	{
		//判断位置合法性,左端已遍历结束
		if (i > mid)
		{
			arr[k] = aux[j - l];
			j++;
		}//判断位置合法性,右端遍历已结束
		else if (j > r)
		{
			arr[k] = aux[i - l];
			i++;
		}//合法情况,进行比较
		else if (aux[i - l] < aux[j - l])
		{
			arr[k] = aux[i - l];
			i++;
		}
		else
		{
			arr[k] = aux[j - l];
			j++;
		}
	}
	delete []aux;
}

template<typename T>
void __MergeSort(T arr[], int l, int r)
{
	if (l >= r)
		return;
	int mid = (l + r) / 2;
	__MergeSort(arr, l, mid);
	__MergeSort(arr, mid + 1, r);
	__Merge(arr, l, mid, r);
}

template<typename T>
void MergeSort(T arr[], int n)
{
	__MergeSort(arr, 0, n - 1);
}

  

原文地址:https://www.cnblogs.com/cyhezt/p/9753805.html

时间: 2024-10-28 19:58:17

高级排序算法之归并排序的相关文章

高级排序算法之归并排序,快速排序

前言 承接上文基础排序算法-冒泡,插入,选择,相比之下,归并排序和快速排序更为高效,时间复杂度均为O(nlogn),相比简单排序的O(n^2)好了很多,下面介绍一下这两种算法的思路,实现和主要指标.主要思路来自<数据结构与算法之美> 正文 归并排序 主要思路 在归并排序采用分冶的思想,使用递归实现.描述如下 开始归并排序 如果数组元素小于两个,无需排序,结束 否则需要排序,归并排序数组左侧,归并排序数组右侧,按序合并左右侧 采用的是自顶至下的思路,例如[1,5,3,7,4,6],左侧为[1,5

数据结构之高级排序算法

一.希尔排序 希尔排序(缩小增量法) 属于插入类排序,由Shell提出,希尔排序对直接插入排序进行了简单的改进:它通过加大插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项大跨度地移动,当这些数据项排过一趟序之后,希尔排序算法减小数据项的间隔再进行排序,依次进行下去,进行这些排序时的数据项之间的间隔被称为增量,习惯上用字母h来表示这个增量. 具体代码实现: 1 package data.struct.algorithm; 2 3 //高级排序算法之希尔排序 4 class

javascript数据结构与算法--高级排序算法

高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法---- 希尔排序和快速排序. 一:希尔排序: 希尔排序的核心理念是:首先比较距离较远的元素,而非相邻的元素. 基本原理:通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔. 下面我们来看看数组[0,9,1,8,7,6,2,3,5,4] 来使用希尔排序的原理:如下图: 代码分析如下: 1. 执行 "间隔序列=3的步骤" A.

排序算法系列——归并排序

记录学习点滴,菜鸟成长记 归并排序的英文叫做Merge-Sort,要想明白归并排序算法,还要从“递归”的概念谈起. 1.递归 一般来讲,人在做决策行事的时候是往往是从已知出发,比如,我又要举个不恰当的例子了→_→: 看到漂亮姑娘→喜欢人家→追→女朋友→老婆 但是人家施瓦辛格不是这么想的,人家从小就立志当总统: 要当总统←先当州长←竞选州长要有钱←那得找个有钱妹子←妹子都喜欢明星←身材好能当明星←健身 递归,就像一个人对自己的发展有清晰的规划和坚定的信心一样,他知道每一步会有怎么样的结果,他需要仅

常用排序算法之——归并排序

归并排序的原理: 如果数组的元素个数大于1,则: 将数组平均分为两部分: 左边的数组归并排序:递归 右边的数组归并排序:递归 将两个各自有序的数组合并,需要一个额外的辅助数组,暂时保存合并结果:返回 否则,数组元素个数为1时,已经有序:直接返回. 稳定排序.时间复杂度在最坏.最好.平均情况下都为O(N lgN),空间复杂度为O(N). 代码: 1 #include <iostream> 2 using namespace std; 3 4 template<typename T>

Java常见排序算法之归并排序

在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let‘s go~~~ 1.排序算法的基本概念的讲解 时间复杂度:需要排序的的关键字的比较次数和相应的移动的次数. 空间复杂度:分析需要多少辅助的内存. 稳定性:如果记录两个关键字的A和B它们的值相等,经过排序后它们相对的位置没有发生交换,那么我们称这个排序算法是稳定的. 否则我们称这个排序算法是不稳定的

高级排序算法之快速排序

快速排序是一个高级排序算法,算法核心思想:确定每一个值的正确位置,即该值左边为小,右边为大即可 这个算法实现上面也是需要经过递归,一般取第一个值开始进行排序 当然也有特别需要注意的地方 设 需要找正确位置的值 定义为 arr[ l ]  = v; 此时需要比较 值 e 与 v 的关系,无非两种(三种即多一个等于) 若e > v ,则无话可说,无需移动,继续移动游标比较arr[ i + 1]  与 v 的大小 若 e < v,则需要交换  e  和 arr [ j + 1 ] 的值,并需要将 j

我的Java开发学习之旅------&amp;gt;Java经典排序算法之归并排序

一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是採用分治法(Divide and Conquer)的一个很典型的应用.将已有序的子序列合并,得到全然有序的序列.即先使每一个子序列有序.再使子序列段间有序.若将两个有序表合并成一个有序表.称为二路归并. 归并过程为:比較a[i]和a[j]的大小.若a[i]≤a[j],则将第一个有序表中的元素a[i]拷贝到r[k]中,并令i和k分别加上1.否则将第二个有序表中的元素a[j]拷贝到r[k]中,并令j和k分别加上1.如此循环下去.直

排序算法之归并排序(Mergesort)解析

一.归并排序的优缺点(pros and cons) 耗费心思来理解它,总要有个理由吧: 归并排序的效率达到了巅峰:时间复杂度为O(nlogn),这是基于比较的排序算法所能达到的最高境界 归并排序是一种稳定的算法(即在排序过程中大小相同的元素能够保持排序前的顺序,3212升序排序结果是1223,排序前后两个2的顺序不变),这一点在某些场景下至关重要 归并排序是最常用的外部排序方法(当待排序的记录放在外存上,内存装不下全部数据时,归并排序仍然适用,当然归并排序同样适用于内部排序...) 缺点: 归并