归并排序,采用的是分治法,各层的分治递归可同时进行。
关于排序原理,我们可以先看一个小动画(图片来自:维基百科)。
归并排序(Mergesort)时间空间复杂度(图片来自:程序师)
看一下归并排序的伪代码:
伪代码:
method mergersort(List list)
if list.size < 2
return list
let middleIndex=list.size/2
let liftList=elements between list(0) and list(middleIndex-1)
let rightList=elements between list(middleIndex) and list(size-1)
let sortedLeft=mergesort(liftList)
let sortedRight=mergesort(rightList)
return merge(sortedLeft,sortedRight)
method merge(List left,List right)
let leftPtr=0
let rightPtr=0
let result=new list
while liftPtr < lift.size && rightPtr < right
if left[leftPtr]<right[rightPtr]
result.add(left[leftPtr])
leftPtr++
else
right.add(left[rightPtr])
rightPtr++
while liftPtr < lift.size
result.add(left[leftPtr])
leftPtr++
while rightPtr < right
right.add(left[rightPtr])
rightPtr++
return result
这是一个分而治之的算法,将两个列表分成两个自列表,分别对这两个子列表进行排序,然后将子列表归并为一个列表。
归并排序Java实现:
package main.java;
import java.util.ArrayList;
import java.util.List;
/**
* DateTime: 2016/10/15 11:35
* 功能:归并排序
* 思路:
*/
public class MergerSort {
public static List<Integer> mergeSort(final List<Integer> values){
if(values.size()<2) return values;
final List<Integer> leftHalf=values.subList(0,values.size()/2);
final List<Integer> rightHalf=values.subList(values.size()/2,values.size());
return merge(mergeSort(leftHalf),mergeSort(rightHalf));
}
public static List<Integer> merge(final List<Integer> left,final List<Integer> right){
int leftPtr=0;
int rightPtr=0;
final List<Integer> merged=new ArrayList<>(left.size()+right.size());
while ( leftPtr<left.size() && rightPtr<right.size() ){
if(left.get(leftPtr)<right.get(rightPtr)){
merged.add(left.get(leftPtr));
leftPtr++;
}else {
merged.add(right.get(rightPtr));
rightPtr++;
}
}
while ( leftPtr<left.size() ){
merged.add(left.get(leftPtr));
leftPtr++;
}
while ( rightPtr<right.size() ){
merged.add(right.get(rightPtr));
rightPtr++;
}
return merged;
}
}
结果测试:
package test.main.java;
import main.java.MergerSort;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertArrayEquals;
/**
* MergerSort Tester.
*
* @author <Authors name>
* @since <pre>ʮ�� 15, 2016</pre>
* @version 1.0
*/
public class MergerSortTest {
/**
*
* Method: mergeSort(final List<Integer> values)
*
*/
@Test
public void testMergeSort() throws Exception {
//归并排序测试
//TODO: Test goes here...
Integer[] array={1,2,3,4,5,6,7,8};
ArrayList arrayList=new ArrayList();
arrayList.add(1);
arrayList.add(8);
arrayList.add(4);
arrayList.add(6);
arrayList.add(2);
arrayList.add(5);
arrayList.add(7);
arrayList.add(3);
assertArrayEquals(array, MergerSort.mergeSort(arrayList).toArray());
}
}
成功通过测试。