1.原理/思路
归并排序的设计思路是:将待排序的数组分为两个字数组,分别对它们按同样的方式进行排序,最后将两个有序子数组
归并成一个有序数组。
2.分析做法
1.将当前序列一分为二,求出分裂点mid = (left + right) / 2;
2.对子序列arr[left,mid]递归,进行归并排序,结果放入data[left,mid]中;
3.对子序列arr[mid+1,right]递归,进行归并排序,结果放入data[mid+1,right]中;
4.调用算法merge,将有序的两个子序列归并成一个有序的序列data[left,right]。
3.代码实现
1. 实现方法一
public int[] mergeSort(int[] arr){
sort(arr,0,arr.length - 1);
return arr;
}
public void sort(int[] arr,int left,int right){
if(left >= right)
return;
int mid = (left + right) / 2;
sort(arr,left,mid);
sort(arr,mid+1,right);
merge(arr,left,mid,right);
}
private void merge(int[] arr,int left,int mid,int right){
int[] temps = new int[right - left + 1];
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right){
if(arr[i] < arr[j]){
temps[k++] = arr[i++];
}else{
temps[k++] = arr[j++];
}
}
while (i <= mid){
temps[k++] = arr[i++];
}
while (j <= right){
temps[k++] = arr[j++];
}
System.out.println("第"+(++number)+"趟排序:\t");
for (int l = 0; l < temps.length; l++) {
arr[left + l] = temps[l];
System.out.print(arr[left + l]+"\t");
}
System.out.println();
}
2. 实现方式二 实现思想和上面一样
private void mergeSort(int[] arr, int l, int r) {
if(l >= r)
return;
int mid = (r + l) / 2;
mergeSort(arr,l,mid);
mergeSort(arr,mid + 1,r);
merge(arr, l, mid, r);
}
private void merge(int[] arr, int l, int mid, int r) {
int[] temp = new int[ r - l + 1];
for (int i = l; i <= r; i++){
temp[i - l] = arr[i];
}
int i = l;
int j = mid + 1;
for (int k = l; k <= r; k++) {
if(i > mid){
arr[k] = temp[j - l];
j++;
}else if(j > r){
arr[k] = temp[i - l];
i++;
}else if(temp[i - l] > temp[j - l]){
arr[k] = temp[j - l];
j++;
}else{
arr[k] = temp[i-l];
i++;
}
}
}
4.测试
@Test
public void test(){
int arr[] = {0,1,1,2,3,3,4,8,7,6,12,22,65};
System.out.println("排序前");
printArr(arr);
int[] data = mergeSort(arr);
System.out.println("排序后");
printArr(data);
}
public void printArr(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
5.总结
归并排序是稳定排序,
可用于链式结构,且不需要附加存储空间,但递归实现时仍需要开辟相应的递归工作栈。