归并排序
归并就是将两个有序数组归并成一个更大的有序数组。使用了分治法的思想
归并排序最吸引人的性质是它能够保证将任意长度为N的数组排序所需时间和NlogN成正比;它的主要缺点则是它需要的额外空间和N成正比.
java中的Collections.sort()方法使用的是归并排序而不是效率最高的快速排序。原因是因为归并排序相比于快排有一个主要的优点:归并排序是稳定的,也就是说归并排序不会改变相等元素的顺序
自顶向下的归并排序
public class 归并排序 {
public static void main(String[] args) {
int[] a={3,5,8,2,6,7,0,9,4,1};
System.out.println("排序前的数组a:");
System.out.println(Arrays.toString(a));
//建立一个临时数组
int[] temp=new int[a.length];
sort(a,0,a.length-1,temp);
System.out.println("排序后的数组a:");
System.out.println(Arrays.toString(a));
}
private static void sort(int[] a, int left, int right, int[] temp) {
int mid;
if (left<right) {
//分成两半
mid = (left + right) / 2;
//左边排序
sort(a, left, mid, temp);
//右边排序
sort(a, mid + 1, right, temp);
merge(a, left, mid, right, temp);
}
}
/**
* 将整个数组分为左右数组两部分
* @param a 数组a
* @param left 左边的数组最左边
* @param mid 整个数组中间位置
* @param right 整个数组最右边
* @param temp 临时数组
*/
private static void merge(int[] a, int left, int mid, int right, int[] temp) {
int i=left;
int k=0;
//j是右边的数组最左边的位置
int j=mid+1;
while(i<=mid && j<=right){
if (a[i]<=a[j]){
temp[k]=a[i];
k++;
i++;
}else{
temp[k]=a[j];
k++;
j++;
}
}
while(i<=mid){
//将左数组剩余元素放入temp数组中
temp[k]=a[i];
i++;
k++;
}
while(j<=right){
//将右数组剩余元素放入temp数组中
temp[k]=a[j];
j++;
k++;
}
for (k=0,i=left;i<=right;i++,k++){
a[i]=temp[k];
}
}
}