归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
使用递归的方式进行做排序。
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* java实现归并排序
* 递归版本的和非递归版本的
*/
public class MergeSortTest {
public static void main(String[] args) {
int []arr=new int[]{9, 8, 7, 6, 5, 4, 3, 2, 10 };
mergesort(arr,0,arr.length-1);
// System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr));
}
private static void mergesort(int[] arr, int left, int right) {
if(left>=right){
return;
}
int mid=left+(right-left)/2;
mergesort(arr,left,mid);
mergesort(arr,mid+1,right);
sort(arr,left,mid,right);
}
private static void sort(int[] arr, int left, int mid, int right) {
int []temp=new int[right-left+1];
int le=left;
int ri=mid+1;
int index=0;
while((le<=mid)&&(ri<=right)){
if(arr[le]>arr[ri]){
temp[index++]=arr[ri++];
}else{
temp[index++]=arr[le++];
}
}
while(le<=mid){
temp[index++]=arr[le++];
}
while (ri<=right){
temp[index++]=arr[ri++];
}
for (int i = 0; i < temp.length; i++) {
arr[i+left]=temp[i];
}
}
}
以下是非递归版本的归并排序,非递归的重点在于如何确定并合理的分解待排序数组。
public class NotMergeSortTest {
public static void main(String[] args) {
int[] arr = new int[]{9, 8, 7, 6, 5, 4, 3, 2, 10};
arr = mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 归并排序
* 非递归版的实现
* 从切分的数组长度为1开始的,一次归并变回原长度的2倍
*
* @param arr
* @return
*/
private static int[] mergeSort(int[] arr) {
int len = 1;
while (len < arr.length) {
for(int i=0;i+len<=arr.length;i+=len*2){
int low=i,mid=i+len-1,high=i+2*len-1;
if(high>arr.length-1){//当为奇数的时候所做的处理
high=arr.length-1;
}
merge(arr,low,mid,high);
}
len *=2;
}
return arr;
}
private static void merge(int[] arr, int low, int mid, int high) {
int[]temp=new int[arr.length];
int right=mid+1;
int index=low;
int begin=low;
while(low<=mid&&right<=high){
if (arr[low]>=arr[right]){
temp[index++]=arr[right++];
}else{
temp[index++]=arr[low++];
}
}
while(low<=mid){
temp[index++]=arr[low++];
}
while(right<=high){
temp[index++]=arr[right++];
}
while(begin<=high){
arr[begin]=temp[begin++];
}
}
}
归并排序比较占用内存,但却是一种效率高且稳定的算法。归并排序的时间复杂度,平均时间复杂度、最坏时间复杂度都为O(nlogn),空间复杂度为T(n)。归并排序算法是稳定性的算法