归并排序
归并排序(Merge-Sort) 是建立在归并操作上的一种有效的排序算法,该算法是采用了分治法的一个典型应用。
具体思想是:
将已经有序的子序列进行合并,从而得到完全有序的序列,即先使得每个子序列有序,在将子序列进行合并,保证合并后是有序的。
上图中:
1、首先对整个序列进行两两拆分,直到每个序列都只有一个数据,
2、然后将子序列依次进行合并,合并的时候进行排序,从而保证合并后的序列都是有序的。
3、重复上述步骤,直到所有的序列被合并为一个序列,这个序列就是归并排序后的序列。
排序的时候,为了不破坏原来的mergeSort方法的参数列表。我们重新定义了他的递归方法mergeSortRec(),
并且定义了一个新的 用于合并的一个方法merge(),
merge方法的具体思路:
1、首先定义一个新的数组,存放合并之后的序列,该数组的长度应该为要合并的两个序列的长度之和,
2、然后依次比较两个有序序列中的数据,将其中较小的数据存放到数组中,并且该序列的下标指针++;
3、重复该步骤,知道两个序列都被遍历完,
4、while循环结束,需要进行一个判断,如果某个序列还剩下数据的话,就将该序列中的元素全部放入新的数组中,这样一来,新的数组中存放的就是合并之后的有序序列了。
5、接下来就是最后一步,将新数组中的元素,分别按照原来的下标,拷贝到原来数组的对应位置。
代码实现如下:
import java.util.Arrays;
/**
* Remarks: 归并排序(递归)
* 时间复杂度:O(n*logn)
* 空间复杂度:O(n)
* 稳定性:稳定
*
* Author:panlai
* :Date:2021/5/13
*/
public class MergeSortTest {
//合并
public static void merge(int[] array,int low ,int mid,int high){
int s1 = low;
int e1 = mid;
int s2 = mid+1;
int e2 = high;
int k = 0;
int[] tmpArr = new int[high-low+1];
while (s1<=e1 && s2<=e2){
if (array[s1] < array[s2]){
tmpArr[k] = array[s1];
k++;
s1++;
}else {
tmpArr[k] = array[s2];
k++;
s2++;
}
}
while (s1<=e1){
tmpArr[k] = array[s1];
k++;
s1++;
}
while (s2<=e2){
tmpArr[k] = array[s2];
k++;
s2++;
}
//将tmparr中的值拷贝到原来数组的对应位置!!
for (int i = 0; i <tmpArr.length ; i++) {
array[i+low] = tmpArr[i];
}
}
public static void mergeSortRec(int[] array,int low,int high){
if (low >= high){
return;
}
int mid = (high+low)>>>1;
mergeSortRec(array,low,mid);
mergeSortRec(array,mid+1,high);
merge(array,low,mid,high);
}
public static void mergeSort(int[] array){
mergeSortRec(array,0,array.length-1);
}
public static void main(String[] args) {
int[] array = {40,52,78,21,8,9};
System.out.println("===============排序前===============");
System.out.println(Arrays.toString(array));
System.out.println("===============归并排序=============");
mergeSort(array);
System.out.println(Arrays.toString(array));
}
}