一、归并排序介绍
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer) 策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修 补"在一起,即分而治之)。
二、归并排序思想示意图1—基本思想
三、归并排序思想示意图2—合并相邻有序子序列
再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将 [4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤
四、代码实现
package cn.zzw.algorithm.sort1;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args)
{
int[] array={ 8, 4, 5, 7, 1, 3, 6, 2 };
int[] temp=new int[array.length];
mergeSort(array,0,array.length-1,temp);
System.out.println(Arrays.toString(array));
}
//分解+合并
public static void mergeSort(int[] arr,int left,int right,int[] temp)
{
if(left<right)
{
int mid=(left+right)/2;
//向左递归进行分解
mergeSort(arr,left,mid,temp);
//向右递归进行分解
mergeSort(arr,mid+1,right,temp);
//合并
merge(arr,left,mid,right,temp);
}
}
//合并的方法,也是归并排序的核心
/**
*
* @param arr 排序的元素组
* @param left 左边有序序列的初始序列
* @param mid 中间索引
* @param right 右边索引
* @param temp 用于中转的数组
*/
public static void merge(int[] arr,int left,int mid,int right,int[] temp)
{
//初始化i为左边有序序列的初始索引
int i=left;
//初始化j为右边有序序列的初始索引
int j=mid+1;
//初始化t指向temp数组的当前索引
int t=0;
//(一)首先先把左右两边有序的数据按照规则填充到temp数组中,直到有一边处理完毕即可
while (i<=mid && j<=right)
{
//如果左边有序序列的当前元素小于等于右边有序序列的当前元素,即将左边的当前元素填充到temp数组中
if(arr[i]<=arr[j])
{
temp[t++]=arr[i++];
}
else
{
//反之将右边有序序列的当前元素填充到temp数组中
temp[t++]=arr[j++];
}
}
//(二)把有剩余数据的一边的数据依次全部填充到temp
while (i<=mid)
{
//此时将左边有序序列中的剩余元素填充到temp中
temp[t++]=arr[i++];
}
while (j<=right)
{
temp[t++]=arr[j++];
}
//(三)将temp数组的元素拷贝到arr中
//注意,并不是每次都拷贝所有
t=0;
int tempLeft=left;
while (tempLeft<=right)
{
arr[tempLeft]=temp[t];
t++;
tempLeft++;
}
}
}