归并排序(MERGE-SORT)
建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
算法描述
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
代码实现:
package com.study.heap;
import java.util.Arrays;
/**
* @Title: MergeSort
* @Description:
* @author: youqing
* @version: 1.0
* @date: 2018/11/17 11:07
*/
public class MergeSort {
public static void main(String []args){
int []arr = {9,5,4,1,3,7,8,2,6};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int []arr){
int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
sort(arr,0,arr.length-1,temp);
}
private static void sort(int []arr,int left,int right,int []temp){
if(left < right){
int mid = (left + right)/2;
sort(arr,left,mid,temp);//左边归并排序,使得左子序列有序
sort(arr,mid+1,right,temp);//右边归并排序,使得右子序列有序
merge(arr,left,mid,right,temp);//将两个有序子数组合并操作
}
}
private static void merge(int []arr,int left,int mid,int right,int []temp){
int i = left;//左序列指针
int j = mid+1;//右序列指针
int t = 0;//临时数组指针
while (i <= mid && j<= right){
if(arr[i]<arr[j]){
temp[t++] = arr[i++];
}else{
temp[t++] = arr[j++];
}
}
while (i <= mid){//将左边剩余元素填充进temp中
temp[t++] = arr[i++];
}
while (j <= right){//将右序列剩余元素填充进temp中
temp[t++] = arr[j++];
}
t = 0;
//将temp中的元素全部拷贝到原数组中
while (left <= right){
arr[left++] = temp[t++];
}
}
}