【DS】排序算法之归并排序(Merge Sort)
一、算法思想
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用,指的是将两个已经排序的序列合并成一个序列的操作。其归并思想如下:
1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
2)设定两个指针,最初位置分别为两个已经排序序列的起始位置;
3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
4)重复步骤3直到某一指针达到序列尾;
5)将另一序列剩下的所有元素直接复制到合并序列尾;
在使用归并排序算法的时候,算法如下:
1)将序列切分,直至切分到序列是有序的(这里通过将序列切分成单个元素达到目的);
2)将序列块两两归并成较大的序列块;
3)将较大的序列块再度归并,不断继续,直至归并形成和原始序列同样大小的序列;
二、算法示意图
如图所示,首先第一行表示待排序的序列,第一步就是将序列元素切割为一个个的独立元素(表示有序序列),接着将相邻的两个元素按照归并思想合并成第二行,同样颜色的元素属于一组,接着再次归并,形成第三行的样子。接着将两组归并,就可以形成最后一行已经排好序的样子。
三、Java代码
public class MergeSort extends Sort {
public static void sort(int[] array) {
int[] tempArray = new int[array.length];
mergeSort(array, tempArray, 0, array.length - 1);
printArray(array);
} private static void mergeSort(int[] array, int[] tempArray, int left, int right ) {
if ( left < right ) {
int center = ( left + right ) / 2;
mergeSort(array, tempArray, left, center);
mergeSort(array, tempArray, center + 1, right);
merge(array, tempArray, left, center + 1, right);
}
} private static void merge( int[] array, int[] tempArray, int left, int right, int end) {
int tempLeft = left;
int tempRight = right;
int position = left; while(tempLeft < right && tempRight <= end){//两个队列都没到头
if(array[tempLeft] < array[tempRight])
tempArray[position++] = array[tempLeft++];
else
tempArray[position++] = array[tempRight++];
} while(tempLeft < right){
tempArray[position++] = array[tempLeft++];
} while(tempRight <= end){
tempArray[position++] = array[tempRight++];
} for(int index = left; index <= end; index++){//复制回去
array[index] = tempArray[index];
}
}
}
算法的精华在于函数mergeSort,这是一个递归算法,从第9行可以看出来,数组首先被切成单个单个的元素,然后再归并。第11~13行首先对左半部分进行归并排序,然后对右半部分进行归并排序,最后整体归并。
四、算法复杂度
这里的分析和快速排序一致,同时,由于它是均分,不会出现和快速排序那样分裂开来的序列不均匀导致的性能差异。我们由函数mergeSort可知,T(n)=O(nlogn)。
由上面的实现代码可知,其空间复杂度为O(n)。我们只需要一个临时数组在合并的时候保存数据即可。
【DS】排序算法之归并排序(Merge Sort)的更多相关文章
- 经典排序算法 - 归并排序Merge sort
经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...
- 排序算法二:归并排序(Merge sort)
归并排序(Merge sort)用到了分治思想,即分-治-合三步,算法平均时间复杂度是O(nlgn). (一)算法实现 private void merge_sort(int[] array, int ...
- 连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)
连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort) 1,起泡排序(bubble sort),大致有三种算法 基本版,全扫描. 提前终止版,如果发现前区里没有发生交换 ...
- Java常见排序算法之归并排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
- java排序算法之冒泡排序(Bubble Sort)
java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...
- 排序算法:归并排序(Merge Sort)
归并排序 归并排序采用了分治策略(divide-and-conquer),就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解. 归并排序将排序数组A[1. ...
- 【排序算法】归并排序算法 Java实现
归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 基本思想 可以将一组数组分成A,B两组 依次类推,当分出来的小组只有一 ...
- STL 源代码剖析 算法 stl_algo.h -- merge sort
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...
- 我的Java开发学习之旅------>Java经典排序算法之归并排序
一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列 ...
随机推荐
- Scracpy爬取图片实例
非常简单,直接上爬虫代码 # -*- coding: utf-8 -*- import scrapy import urllib import logging class TopitComSpider ...
- Markdown 入门指南
导语: Markdown是一种轻量级的标记语言,语法简单,学习成本不算太高,但确实可以让你专注于文字,不用太分心与排版等等. Markdown 官方文档 这里可以看到官方的Markdown语法规则: ...
- Kafka API: TopicMetadata
Jusfr 原创,转载请注明来自博客园 TopicMetadataRequest/TopicMetadataResponse 前文简单说过"Kafka是自描述的",是指其broke ...
- 关于Map迭代循环,key和value的顺序问题
使用Hashtable,keySet()返回的顺序为降序(key降顺序) ---->6, 5, 4, 3, 2, 1使用TreeMap,keySet()返回的顺序为升序(key升顺序) ---- ...
- OpenGL:使用顶点数组法绘制正六面体
在今天的opengl的课程以及实验中,我们学习了如何使用顶点数组的方法来绘制图形,但相信还有很多同学对它的实际使用方法不太了解,我们就用我们今天实验课上的实例来简单讲解一下 题目及要求 绘制一个正六面 ...
- DevOps架构下如何进行微服务性能测试?
一. 微服务架构下的性能测试挑战 微服务与DevOps 微服务是实现DevOps的重要架构 微服务3S原则 DevOps核心点 微服务架构下的业务特点 亿级用户的平台 单服务业务随时扩容 服务之间存在 ...
- 科普贴 | 数字钱包MetaMask安装使用详解,活用MetaMask轻松驾驭以太坊
MetaMask 是一款浏览器插件钱包,不需下载安装客户端,只需添加至浏览器扩展程序即可使用,非常方便.它是很多支持 ETH 参投的 ICO 项目推荐使用的钱包之一. 2018年初最火的一个币,应该就 ...
- Android 使用 OnTouchListener 接口监听双击或多击事件
这里是使用 OnTouchListener 实现的监听双击 or 多击的监听器.通过 View.setOnTouchListener ,可以实现在任意 View 上监听双击事件. 网上有许多文章简单的 ...
- PAT甲题题解-1033. To Fill or Not to Fill (25)-模拟
模拟先说一下例子,最后为方便起见,在目的地安增加一个费用为0的加油站0 1 2 3 4 5 6 7 87.1 7.0 7.2 6.85 7.5 7.0 7.3 6.0 00 150 200 300 4 ...
- 【SE】Week3 : 个人博客作业(必应词典)
关于 微软必应词典客户端 的案例分析 [第一部分] 调研,评测 一.用户采访 1) 介绍采访对象的背景和需求: 被采访同学是马来西亚华裔叶能端同学,由于此前在马来西亚英语是第二语言,因此经常需要 ...