归并排序
在排序算法中快速排序的效率是非常高的,但是还有种排序算法的效率可以与之媲美,那就是归并排序;归并排序和快速排序有那么点异曲同工之妙,快速排序:是先把数组粗略的排序成两个子数组,然后递归再粗略分两个子数组,直到子数组里面只有一个元素,那么就自然排好序了,可以总结为先排序再递归;归并排序:先什么都不管,把数组分为两个子数组,一直递归把数组划分为两个子数组,直到数组里只有一个元素,这时候才开始排序,让两个数组间排好序,依次按照递归的返回来把两个数组进行排好序,到最后就可以把整个数组排好序;
时间复杂度O( nlogn )
归并的时间复杂度分析:主要是考虑两个函数的时间花销,一、数组划分函数mergeSort();二、有序数组归并函数_mergeSort();
_mergeSort()函数的时间复杂度为O(n),因为代码中有2个长度为n的循环(非嵌套),所以时间复杂度则为O(n);
简单的分析下元素长度为n的归并排序所消耗的时间 T
:调用mergeSort()函数划分两部分,那每一小部分排序好所花时间则为 T[n/2],而最后把这两部分有序的数组合并成一个有序的数组_mergeSort()函数所花的时间为 O(n);
公式:T
= 2T[n/2] + O(n);
公式就不仔细推导了,可以参考下: 排序算法之快速排序及其时间复杂度和空间复杂度里面时间复杂度的推导;
所以得出的结果为:T
= O( nlogn )
因为不管元素在什么情况下都要做这些步骤,所以花销的时间是不变的,所以该算法的最优时间复杂度和最差时间复杂度及平均时间复杂度都是一样的为:O( nlogn )
空间复杂度为 O(n)
归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为: O(n)
代码:
package MergeSort;
public class MergeSort1 {
public static void main(String[] args) { int [] arr = {12,4,17,2,7,19,10,32,1,8,9}; mergeSort(arr); print(arr); } private static void mergeSort(int[] arr) { sort(arr, 0, arr.length - 1); } private static void sort(int[] arr, int left, int right) { if(left<right){ int lmiddle = (left+right)/2; sort(arr,0,lmiddle); sort(arr,lmiddle+1,right); merge(arr,left,lmiddle,right); } } private static void merge(int[] arr, int left, int lmiddle, int right) { //定义一个新的数组 int[] temArr = new int[arr.length]; //记录右数组的第一个数的索引 int rmiddle = lmiddle+1; //记录左数组的第一索引 int temp = left; //记录临时数组的索引 int index = left; while(left<=lmiddle&&rmiddle<=right){ if(arr[left]<arr[rmiddle]){ temArr[index++]=arr[left++]; }else{ temArr[index++]=arr[rmiddle++]; } } //将剩余数组存放进去 while(rmiddle<=right){ temArr[index++]=arr[rmiddle++]; } while(left<=lmiddle){ temArr[index++]=arr[left++]; } //将临时数组的值保存到原数组 while(temp<=right){ arr[temp]=temArr[temp++]; } } private static void print(int[] arr) { for(int i :arr){ System.out.print(i+"\t"); } }
}
- POJ 2299 Ultra-QuickSort 树状数组,归并排序
- 归并排序
- 归并排序和堆排序
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——C++实现
- POJ2299 Ultra-QuickSort(归并排序求逆序数)
- 排序算法(四)——归并排序与递归
- 归并排序(Merge Sort)
- 归并排序求逆序
- 归并排序(C/C++)
- POJ 2299 Ultra-QuickSort(归并排序)
- 排序算法:归并排序
- 数据结构之---C语言实现归并排序
- SDUT 3317 反演 归并排序 求逆序数
- 归并排序
- 归并排序的利用
- 排序算法之归并排序
- 归并排序
- Java一步一脚—排序(最基本的排序,两种快排,归并排序
- noip2013 火柴排队 (离散化+归并排序求逆序对数)
- 归并排序