归并排序:
归并排序是利用归并的思想实现的排序算法,该算法采用经典的分治策略(分治法是将问题分成一些小的问题然后递归求解,而治的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
基本思想:
分的阶段就是递归拆分子序列的过程,治的阶段就是将俩个有序的子序列合并成一个有序的序列。
动态图解:
Java代码实现:
import java.util.Scanner;
public class Merge_sort {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入数组的大小:");
Scanner input = new Scanner(System.in);
int a = input.nextInt();
int [] arr = new int[a];
for(int i = 0;i<arr.length;i++) {
System.out.println("请输入数组的第"+i+"个值:");
int s = input.nextInt();
arr[i] = s;
}
arr = MergeSort(arr,0,arr.length-1);
for(int i = 0;i<arr.length;i++)
System.out.print(" "+arr[i]+" ");
}
public static int[] MergeSort(int[] arr,int start,int end) {
//归并排序:
//分治法!
//基本思想:将俩个或俩个以上的有序表合并成一个新的有序表,
//即把待排序序列分为若干个子序列,每个子序列都是有序的。然后再把有序子序列合并为整体有序序列
//可以通过俩种方法来实现:自上而下递归、自下而上迭代
//递归:
//将序列每相邻俩个数字进行归并操作,行成floor(n/2)个序列,排序后每个序列包含俩个元素
//将上述序列再次归并,行程floor(n/4)个序列,每个序列包含4个元素
//重复步骤2,直到所有元素排序完毕
//迭代:
//申请空间,使其大小为俩个已经排序序列之和,该空间用来存放合并后的序列
//设定俩个指针,最初位置分别为俩个已经排序序列的起始位置
//比较俩个指针所指向的元素,选择相对较小的元素放入到合并的空间,并移动指针到下一位置
//重复步骤3直到某一指针到达序列队尾
//将另一序列剩下的所有元素直接复制到合并序列尾
if(start<end) {
int mid = (start + end)/2;
//将左边的序列进行划分
MergeSort(arr,start,mid);
//将右边的序列进行划分
MergeSort(arr,mid+1,end);
//将左右俩边的序列归并
Merge(arr,start,mid,end);
}else return null;
return arr;
}
public static int[] Merge(int[] arr,int start,int mid,int end) {
//创建一个新的数组来容纳左右俩边的元素
//数组长度为最后一个元素的下标减去第一个元素的下标再加1
int[] temp = new int[end-start+1];
//定义左边序列的指针
int i = start;
//定义右边序列的指针,为中间值+1
int j = mid+1;
//新的数组的元素下标
int k = 0;
//把较小的数先移到新的数组中
while(i<=mid&&j<=end) {
if(arr[i]<arr[j])
temp[k++] = arr[i++];
else
temp[k++] = arr[j++];
}
//如果右边序列的值全都放入到新数组中,左边序列还有部分值,
//则将左边序列剩余元素直接放入到数组
while(i<=mid)
temp[k++] = arr[i++];
//如果左边序列的值全都放入到新数组中,右边序列还有部分值,
//则将右边序列剩余元素直接放入到数组
while(j<=end)
temp[k++] = arr[j++];
//把新数组中的数覆盖原数组
for(int o=0;o<temp.length;o++)
arr[start+o] = temp[o];
return arr;
}
}