归并排序
分治法
分治法可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。
分治法的精髓:
分--将问题分解为规模更小的子问题;
治--将这些规模更小的子问题逐个击破;
合--将已解决的子问题合并,最终得出“母”问题的解;百度百科
归并排序的复杂度
归并排序是一种稳定的排序算法,归并排序的主要问题在于它需要一个与待排序数组一样大的辅助数组空间。由于归并排序每次划分时两个子序列的长度基本一样,所以归并排序最好、最差和平均时间复杂度都是nlog2n。
算法描述
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
java实现
import static java.lang.Float.POSITIVE_INFINITY;
public class MergeSort{
public static void main(String[] args) {
int arr[]={1,5,6,8,7,4,3,9};
MergeSort_Manger(arr,0,arr.length-1);
for (int e:arr)
{
System.out.print(e+"\t");
}
}
private static void MergeSort_Manger(int[] arr, int begin, int end) {
if(begin<end){
int mid=(begin+end)/2;
MergeSort_Manger(arr,begin,mid);//对左段进行排序
MergeSort_Manger(arr,mid+1,end);//对右段进行排序
MergeSort(arr,begin,mid,end);//合并
}
}
private static void MergeSort(int[] arr, int begin, int mid, int end) {
/*
* 1.设置两个临时的数组,分别存放数组的前半段和后半段
* 2.把两个数组的最后一位赋值为无穷大
* 3.比较两个数组,把相对较小的值(最小值)插入到原数组的begin位
* */
int n1=mid-begin+1;
int n2=end-mid;
int[] L= new int [n1+1];
int[] R= new int [n2+1];
L[n1]=(int)POSITIVE_INFINITY;//正无穷大
R[n2]=(int)POSITIVE_INFINITY;
for (int i = 0; i <n1; i++) {
L[i]=arr[begin+i];
}
for (int i = 0; i <n2; i++) {
R[i]=arr[mid+i+1];
}
int k=0,i=0,j=0;
for ( k=begin;k<=end;k++){
if (R[i]<L[j]){
arr[k]=R[i++];
}
else
arr[k]=L[j++];
}
}
}