算法分析:是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
复杂度:
数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取。
public void mergesort(int[]arr,int low,int high){
int middle=(high+low)/2;
if(low<high){
mergesort(arr,low,middle);
mergesort(arr,middle+1,high);
merge(arr,low,middle,high);
}
}
public void merge(int[]arr,int low,int middle,int high){
//用于存储归并后的临时数组
int[] temp=new int[high-low+1];
//用于记录第一个数组中需要遍历的下标
int i=low;
//用于记录第二个数组中需要遍历的下标
int j=middle+1;
//记录在临时数组中存放的下标
int index=0;
while(i<=middle&&j<=high){
//第一个数组的数据更小
if(arr[i]<=arr[j]){
//把小的数据放入临时数组中
temp[index]=arr[i];
//让下标向后一位
i++;
}else{
temp[index]=arr[j];
j++;
}
index++;
}
//处理多余的数据
while(j<=high){
temp[index]=arr[j];
j++;
index++;
}
while(i<=middle){
temp[index]=arr[i];
i++;
index++;
}
//放回数组
for(int k=0;k<temp.length;k++){
arr[k+low]=temp[k];
}
}