归并排序(Merge Sort)
归并操作的工作原理如下:
效率为O(n log n)
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
(1)算法思想
归并排序采用了分治策略(divide-and-conquer),就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解。
归并排序将待排序数组A[1..n]
分
成两个各含n/2个元素的子序列,然后对这个两个子序列进行
递归
排序,最后将这两个已排序的子序列进行
合并
,即得到最终排好序的序列。
具体排序过程如下图所示:
排序图:
分别从左到右比较两个数组中哪一个值比较小,然后复制进新的数组中,一直比较到两个数组中有某一个先到末尾为止,最后把另一个数组中的剩余元素复制进新数组即可。
将一个数组一直对半分,问题的规模就减小了,再重复进行这个过程,直到元素的个数为一个时,一个元素就相当于是排好顺序的。
由于前提是这个两个数组都是有序的,所以这整个过程是很快的,我们可以看出,对于一对长度为N的数组,进行合并所需要的比较次数
最多为2 * N -1。
package com.sunMac.eightSort;
/**
复杂度:
*
* @author sun.JH
*归并排序(递归)
*/
public class mergeSort {
public static void main(String[] args) {
int a[] = {51,46,20,18,65,97,82,30,77,50};
sortarray(a);
for (int i : a) {
System.out.print("-->"+i);
}
}
//外部接口方法
public static void sortarray(int[]a){
int low=0;
int high=a.length-1;
mergeSort(a,low,high);
}
//递归排序的方法
private static void mergeSort(int[]a,int low,int high) {
int mid=(low + high)/2;
//每次对半
if (low < high){
mergeSort(a,low,mid);
//左边
mergeSort(a,mid+1,high);
//右边
merge(a,low,mid,high);
//左右归并
for (int i : a) {
System.out.print("递归排:"+i);
}
System.out.println();
}
}
private static void merge(int[] a,int low,int mid,int high) {
int[] temp = new int[high-low+1];
int i = low;
// 左指针
int j = mid + 1;
// 右指针
int k = 0;
// 把较小的数先移到新数组中
while (i<= mid&&j<= high) {
if (a[i] < a[j]){
temp[k++]=a[i++];
}else{
temp[k++]=a[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = a[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = a[j++];
}
// 把新数组中的数覆盖原数组
for (int k2 = 0; k2 < temp.length; k2++) {
a[k2 + low] = temp[k2];
}
}
}