闲聊几句,先说说我为什么要写这些东西,有人说是炒冷饭,呵呵,其实本意是为了锻炼自己的写作能力,希望能把一个知识点深入浅出的表达出来,说着容易,但是对于一个新手,则需要一个很长的过程,之前一直没有意识到这块儿的薄弱性,所以打算通过写技术blog来锻炼自己,二是为了梳理一下自己的知识结构体系,三是为了分享自己的心得。所以刚刚开始时,难免文章有生硬的地方,打个比方,很可能写的东西,网上已经有很多类似的文章,并且总结的很好,图文并茂,看了之后 ,总有拷贝的冲动,但是里边总会有自己的体会,记录一下思想,以后再回顾的时候,一看,哦,当初是这样思考的,这个过程,我认为才是最重要的,所以即便是炒冷饭,我也要冷饭硬炒 !
开始今天的学习,归并排序,本来打算跟快速排序一起写,发现效果不好,本着一篇文章一个知识点的初衷,这里我先单介绍一下归并排序,回头在写一篇关于各个排序的对比和选择:
1。归并排序
定义:也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作,属于分治法(Divide and Conquer)的一个非常典型的应用。
基本思路:
-
Divide: 把长度为n的输入序列分成两个长度为n/2的子序列。
-
Conquer: 对这两个子序列分别采用归并排序。
-
Combine: 将两个排序好的子序列合并成一个最终的排序序列
数组的代码实现:
public void mergeSort(int[] data, int left, int right) {
if (left < right) {
int mid = (left + right) >>> 1;
// 对左半部份排序
mergeSort(data, left, mid);
// 对有半部分排序
mergeSort(data, mid + 1, right);
// 合并到一个临时数组,再拷贝到data中
merge(data, left, mid, right);
}
}
public void merge(int[] data, int left, int mid, int right) {
int mergeleft, mergeright, index;
int[] temp = new int[right - left + 1];
mergeleft = left;
mergeright = mid + 1;
index = 0;
// 选择排序
while ((mergeleft <= mid) && (mergeright <= right)) {
if (data[mergeleft] < data[mergeright]) {
temp[index++] = data[mergeright++];
} else {
temp[index++] = data[mergeleft++];
}
// 剩下的数据拷贝到temp中
for (int rest = mergeleft; rest < mid; rest++) {
temp[index] = data[rest];
}
for (int rest = mergeright; rest < right; rest++) {
temp[index] = data[rest];
}
int pos = left;
for (index = 0; index < data.length; index++) {
data[pos] = temp[index];
}
}
再看下JDK中对象排序的实现,Arrays.sort(int[] a):
public static void sort(Object[] a) {
Object[] aux = (Object[])a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
int length = high - low;
// 如果数组的长度小于7,则采用插入排序
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
这里我们看到对对象的排序采用的是归并算法,大体流程跟数组排序是一样的,只不过待排序对象数组要实现Comparable接口 。
2.时间复杂度分析
比较操作的次数介于(nlogn) / 2和nlogn − n + 1。 赋值操作的次数是(2nlogn)。 归并算法的空间复杂度为:Θ (n)
3.总结
如果大家看完上边的代码,感觉没有理解的话,建议把代码拷贝到IDE里边,DEBUG一下,一步一步的跟踪,也许这样你会比较深刻的理解分治法的思想,网上有很多归并算法的图形演示,但是刚开始的时候如果你看图,再学习代码,会有种分裂的感觉,至少我是这样,所以如果最后实在理解不了,也不要钻牛角尖,毕竟只是一个算法,大家只要理解其思想就可以了,或者我们能在实际编程中使用就行。
简单总结一下代码实现,对已有的数据序列,首先利用递归(网上没有看到用迭代方式实现的JAVA代码)逐层等分序列,直到最后只剩下两个一对的集合,然后开始逐层向上先排序再合并,期间的每次合并都需要一个中间的临时数组,直到合并为初始数组,这是所有的数据为已排序状态。这里我就不再画图了,网上有很多例子,感兴趣可以用google搜索一下。
最后上传一个GIF图片,提高一下感性认识,此图片来源于维基百科
随机点的进行归并排序
http://zh.wikipedia.org/zh-cn/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F
- 大小: 13.1 KB
分享到:
相关推荐
归并排序是一种高效的排序算法,源自分治策略。在数据结构和算法领域,它占据了重要的地位,尤其在处理大量数据时表现出优秀的性能。《数据结构》严蔚敏版是计算机科学的经典教材,其中对归并排序有深入的阐述。下面...
其中,排序算法是数据结构领域的一个重要分支,它的目标是将无序的数据序列整理成有序序列。归并排序(Merge Sort)是一种非常有效的排序算法,尤其在处理大量数据时表现出良好的稳定性和效率。 归并排序的基本思想...
排序算法则是数据结构中的重要部分,它们用于对一组数据进行有序排列。在这个实验中,我们将关注六种不同的排序算法:选择排序、冒泡排序、插入排序、基数排序以及快速排序和归并排序。下面是对这些排序算法的详细...
在计算机科学领域,排序算法是数据...了解和掌握这些排序算法,以及它们在不同数据结构上的应用,对于提升编程技能和解决实际问题具有重要意义。在实际开发中,根据数据特性选择合适的排序算法,能有效提高程序性能。
首先,堆排序是一种基于比较的排序算法,利用了二叉堆的数据结构。二叉堆是一个完全二叉树,可以分为最大堆或最小堆,其中每个父节点的值都大于或等于其子节点。堆排序的过程包括构建初始堆和调整堆。首先,将无序...
【数据结构与排序算法在Java中的应用】 在计算机科学中,数据结构是组织和存储数据的方式,而排序算法则是对这些数据进行排列的策略。在Java编程中,掌握各种排序算法对于提高程序效率至关重要。本篇文章将深入探讨...
5. 归并排序(Merge Sort):归并排序也是基于分治法,将数组分成两半,分别排序,再合并。它的时间复杂度稳定在O(n log n),但需要额外的内存空间。 6. 堆排序(Heap Sort):堆是一种特殊的树形数据结构,堆排序...
递归是计算机科学中的一个重要概念,它在数据结构和算法设计与分析中应用广泛。递归策略在解决许多问题时提供了简洁而强大的方法,尤其是在涉及树状结构数据(例如二叉树)和特定排序算法(如归并排序)的设计时。...
数据结构是计算机科学中的核心课程...总的来说,"数据结构课设排序算法的可视化演示(QT+C++)"是一个综合性的项目,它涵盖了数据结构、算法、编程和可视化等多个方面,对于提升计算机科学学生的综合素质具有重要意义。
9. **总结**:归并排序是一种高效的排序算法,适用于处理大规模数据。其稳定性和O(n log n)的时间复杂度使其在很多场景下成为首选。然而,由于空间复杂度较高,需要根据具体需求权衡使用。理解归并排序的工作原理...
使用MFC单文档实现数据结构8种排序算法的图形界面动态演示,更加形象的展示排序过程,八种排序算法包括插入排序(直接插入排序、折半插入排序、希尔排序)、选择排序(直接选择排序、堆排序)、交换排序(冒泡排序、...
在IT领域,数据结构与算法是基础且至关重要的部分,特别是排序算法,它们在软件开发中扮演着核心角色。本文将深入探讨“数据结构与算法之排序”,重点关注内部排序和外部排序。 首先,我们理解一下数据结构。数据...
实现以下常用的内部排序算法并进行性能比较:"直接插入排序"," 折半插入排序"," 2—路插入排序"," 表插入排序"," 希尔排序"," 起泡排序"," 快速排序"," 简单选择排序"," 树形选择排序"," 堆排序"," 归并排序"," 链式...
2. **归并排序**:归并排序是基于分治法的排序算法,将数据不断分成两半,直到每个子序列仅包含一个元素,然后将这些元素按顺序合并回原序列。归并排序具有稳定性,但需要额外的空间来存储子序列。 3. **堆排序**:...
根据提供的实验报告信息,我们可以详细地探讨数据结构中查找与排序算法的相关知识点,具体包括折半查找、顺序查找、归并排序以及堆排序这四种算法。 ### 一、折半查找 #### 定义与原理 折半查找,也称二分查找,是...
在计算机科学领域,数据结构和排序算法是编程基础的重要组成部分,特别是对于C语言这样底层而强大的编程工具。本文将深入探讨“C语言数据结构内部排序算法及比较”这一主题,结合个人课程作业的经验,对一些核心概念...
### 数据结构:归并排序(非递归算法) #### 算法介绍 归并排序是一种高效的、基于比较的排序算法,它采用分治策略来对数组进行排序。归并排序可以递归地将数组分成更小的部分,然后将这些部分合并起来形成有序...
### 数据结构 VC实现 归并排序 #### 一、归并排序原理介绍 归并排序是一种采用分治法策略的高效排序算法。其核心思想是将待排序的序列分为尽可能相等的两部分,分别对这两部分进行排序,然后将排好序的两部分合并...
### 归并排序:经典数据结构算法 #### 算法概述 归并排序是一种经典的、高效的基于比较的排序算法,其基本思想是采用分治法(Divide and Conquer)。该算法首先将待排序的序列分成若干个子序列,每个子序列都是...