归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
中文名称:归并排序 ; 时间复杂度:O(n log n)
外文名称:Merge sort ;空间复杂度:O(n)
稳定性:稳定 ; 发明者:约翰·冯·诺伊曼
如图所示,视图分析归并排序:
代码实现:
1、创建归并排序方法:
public static void mergeSort(int[] array){
for(int i = 1;i <= array.length-1;i = i*2){//每一次归并段数据翻倍
merge(array,i);//调用merge()方法
}
}
2、创建merge()方法:
public static void merge(int[] array,int gap){//每个归并段的数据个数
//给变量赋初值
int start1 = 0;
int end1 = start1+gap-1;
int start2 = end1+1;
int end2 = start2+gap-1 < array.length-1?start2+gap-1:array.length-1;
//排序
int[] tmpArr = new int[array.length];//将array中的元素从小到大放入tmpArr中
int i=0;//tmpArr下标
while(start2 < array.length){
//比较元素 s1 s2 s1 s2++
//第一种情况:两个归并段是否都有数据
while(start1 <= end1 && start2 <= end2){
if(array[start1] > array[start2]){//每次都只比较 start1 和 start2 下标所对应的元素
tmpArr[i++]=array[start2];
start2++;
}else{
tmpArr[i++]=array[start1];
start1++;
}
}
//第二种情况:第一个归并段有数据
while(start1 <= end1){
tmpArr[i++]=array[start1];
start1++;
}
//第三种情况:第二个归并段有数据
while(start2 <= end2){
tmpArr[i++]=array[start2];
start2++;
}
//循环未结束,换后边的归并段进行排序
start1 = end2+1;
end1 = start1+gap-1;
start2 = end1+1;
end2 = start2+gap-1 < array.length-1?start2+gap-1:array.length-1;
}
//若一开始整个array的就不够一个归并段的大小
while(start1 < array.length){
tmpArr[i++] = array[start1++];
}
//剩下的s1 end1之间的内容需要放进来tmpArr
for(int j=0;j < tmpArr.length;j++){
array[j] = tmpArr[j];
}
}
3、测试:
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array={113,46,78,23,45,1,5,7,8,32};
mergeSort(array);
System.out.println(Arrays.toString(array));
}
输出结果: