Java排序算法之归并排序
来源:互联网 发布:linux 驱动 usleep 编辑:程序博客网 时间:2024/06/05 09:27
Java排序算法之归并排序
算法概述
归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为两路归并排序算法。
算法思想
归并排序就是利用归并的思想实现的排序方法。而且充分利用了完全二叉树的深度是的特性,因此效率比较高。其基本原理如下:对于给定的一组记录,利用递归与分治技术将数据序列划分成为越来越小的半子表,在对半子表排序,最后再用递归方法将排好序的半子表合并成为越来越大的有序序列。 经过第一轮比较后得到最小的记录,然后将该记录的位置与第一个记录的位置交换;接着对不包括第一个记录以外的其他记录进行第二次比较,得到最小记录并与第二个位置记录交换;重复该过程,知道进行比较的记录只剩下一个为止。
两路归并排序算法思想:
①把 n 个记录看成 n 个长度为1的有序子表;
②进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表;
③重复第②步直到所有记录归并成一个长度为 n 的有序表为止。
详细步骤:
1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列(申请的内存空间大小必须大于等于待排序数组的长度)。
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置。
3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
4、重复步骤3直到某一指针达到序列尾。
5、将另一序列剩下的所有元素直接复制到合并序列尾。
算法源码
/** * 归并排序 * * @author Administrator * */public class MergeSort { public static void merge_sort(int a[],int first,int last,int temp[]){ if(first < last){//使用递归算法将左、右两部分排好序。 int middle = (first + last)/2; merge_sort(a,first,middle,temp);//左半部分排好序 System.out.print("左半部分排序结果:"); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + "\t"); } System.out.println(""); merge_sort(a,middle+1,last,temp);//右半部分排好序 System.out.print("右半部分排序结果:"); for (int j = 0; j < a.length; j++) { System.out.print(a[j] + "\t"); } System.out.println(""); mergeArray(a,first,middle,last,temp); //合并左右部分 } } //合并 :将两个序列a[first-middle],a[middle+1-end]合并 public static void mergeArray(int a[],int first,int middle,int end,int temp[]){ int i = first;//要排序数组的第一个数下标 int m = middle;//要排序数组的中间数下标 int j = middle+1; int n = end;//要排序数组的最后一个数下标 int k = 0; while(i<=m && j<=n){ if(a[i] <= a[j]){ temp[k] = a[i]; k++; i++; }else{ temp[k] = a[j]; k++; j++; } } while(i<=m){ temp[k] = a[i]; k++; i++; } while(j<=n){ temp[k] = a[j]; k++; j++; } for(int ii=0;ii<k;ii++){ a[first + ii] = temp[ii]; } } public static void main(String[] args) { int array[]={100,30, 111,46,99,-1,53,20}; int temp[]=new int[8];//申请分配内存>=array.length merge_sort(array, 0, array.length-1, temp); System.out.print("最终排序结果:"); for (int a = 0; a < array.length; a++) { System.out.print(array[a] + "\t"); } }}
测试效果:
左半部分排序结果:100 30 111 46 99 -1 53 20 右半部分排序结果:100 30 111 46 99 -1 53 20 左半部分排序结果:30 100 111 46 99 -1 53 20 左半部分排序结果:30 100 111 46 99 -1 53 20 右半部分排序结果:30 100 111 46 99 -1 53 20 右半部分排序结果:30 100 46 111 99 -1 53 20 左半部分排序结果:30 46 100 111 99 -1 53 20 左半部分排序结果:30 46 100 111 99 -1 53 20 右半部分排序结果:30 46 100 111 99 -1 53 20 左半部分排序结果:30 46 100 111 -1 99 53 20 左半部分排序结果:30 46 100 111 -1 99 53 20 右半部分排序结果:30 46 100 111 -1 99 53 20 右半部分排序结果:30 46 100 111 -1 99 20 53 右半部分排序结果:30 46 100 111 -1 20 53 99 最终排序结果:-1 20 30 46 53 99 100 111
这样效果不是很好,把左半部分排序和右半部分排序分开:
左半部分排序
左半部分排序结果:100 30 111 46 99 -1 53 20 左半部分排序结果:30 100 111 46 99 -1 53 20 左半部分排序结果:30 100 111 46 99 -1 53 20 左半部分排序结果:30 46 100 111 99 -1 53 20 左半部分排序结果:30 46 100 111 99 -1 53 20 左半部分排序结果:30 46 100 111 -1 99 53 20 左半部分排序结果:30 46 100 111 -1 99 53 20
右半部分排序
右半部分排序结果:100 30 111 46 99 -1 53 20 右半部分排序结果:30 100 111 46 99 -1 53 20 右半部分排序结果:30 100 46 111 99 -1 53 20 右半部分排序结果:30 46 100 111 99 -1 53 20 右半部分排序结果:30 46 100 111 -1 99 53 20 右半部分排序结果:30 46 100 111 -1 99 20 53 右半部分排序结果:30 46 100 111 -1 20 53 99
其排序过程完全按照其算法步骤来实现。
算法分析
(1)稳定性
归并排序是一种稳定的排序。
(2)存储结构要求
可用顺序存储结构。也易于在链表上实现。
(3)时间复杂度
对长度为n的文件,需进行趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)
(4)空间复杂度
需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
注意:若用单链表做存储结构,很容易给出就地的归并排序。
总结
归并排序 (merge sort) 是一类与插入排序、交换排序、选择排序不同的另一种排序方法。归并排序是一种比较占内存,但却效率高且稳定的算法。归并的含义是将两个或两个以上的有序表合并成一个新的有序表。归并排序有多路归并排序、两路归并排序 , 可用于内排序,也可以用于外排序。
- java算法之归并排序
- java算法之归并排序
- 排序算法之归并排序(JAVA)
- Java排序算法之归并排序
- 排序算法之归并排序Java版
- Java实现排序算法之归并排序
- 排序算法之归并排序(JAVA)
- java排序算法之--归并排序
- 排序算法之归并排序(Java)
- 排序算法之归并排序(JAVA)
- 排序算法之归并排序 java
- 排序算法之归并排序(JAVA)
- 排序算法之归并排序java实现
- 排序算法之归并排序(JAVA)
- Java排序算法之归并排序
- 排序算法之归并排序(JAVA)
- Java排序算法之归并排序
- 排序算法之归并排序--Java语言
- 线程的两种实现方式,以及区别
- JMter通过JDBC请求进行数据库压力测试
- 网易2017招聘笔试题<下厨房>Java代码
- Post/get 提交调用抓取Url获取json字符串
- 网络唤醒全攻略(Wake On Lan)
- Java排序算法之归并排序
- Element-ui框架修改-upload、step
- Nginx+PHP+MySQL
- C语言中 不定义结构体变量求成员大小
- py2字符编码相关
- js_swal的使用
- C++中static和const
- js获取jsp页面中嵌入的java代码中的变量
- struts2自定义返回类型