归并排序思路:
把数组中的每一个元素看做是一个有序表,把相邻的两个表进行归并,组成一个新的有序表并不断以此类推直到最后变成一个有序表。
时间复杂度:
O(NlogN)
空间复杂度:
O(N) 因为需要一个临时数组来存储当前归并后的表并最后赋值回来
实现思路:
- 递归实现把当前的数组分割成若一个个单个的元素通过递归的方式想,相当于二分法,分割完之后再对分割完的两个进行归并操作。
- 递归的最深层是分割成了两个独立的元素,在合并后依次往外进行弹出,最后形成一张有序的表
- 归并函数,就是不断吧两个表中较小的元素存储到临时的数组中之后再赋值回来的过程。要十分注意最后赋值的方法,是吧当前i到j的元素赋值回来要不然原来的数组元素逻辑就乱了。
代码:
package 归并排序;
//归并排序
public class MergeSort {
public static void sort(int[] array,int i,int j){
//对其进行排序处理
if(i<j){
//对其进行分解处理底层拆分成单个元素的有序表进行两两归并
int middle = (i+j)/2;
sort(array,i,middle);
sort(array,middle+1,j);
merge(array,i,middle,j);
}
}
public static void merge(int[] array,int i,int middle,int j){
//左有序表的起始索引
int left = i;
//右有序表的起始索引
int right = middle+1;
//临时存储数组的索引
int index = i;
//临时存储数组
int[] temp = new int[array.length];
//把两个有序表按照升序排列,如果长度不同则长度有序表元素有剩余
while(left<=middle && right<=j){
if(array[left]<=array[right]){
temp[index++] = array[left++];
}else{
temp[index++] = array[right++];
}
}
while(left<=middle&&right<=j)
{
if(array[left]<array[right])
temp[index++]=array[left++];
else
temp[index++]=array[right++];
}
//当左有序表元素有剩余的时候给与赋值
while(left<=middle){
temp[index++] = array[left++];
}
//当右有序表元素有剩余的时候给与赋值
while(right<=j){
temp[index++] = array[right++];
}
//把临时的数组元素赋予给真正变化的数组
while(i<=j)
{
array[i]=temp[i++];
}
}
public static void main(String[] args){
int[] array = {13,42,52,25,63,1,2,35,7,9};
System.out.println("归并排序前:");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
System.out.println("归并排序后:");
sort(array, 0, array.length-1);
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
}
结果:
归并排序前:
13 42 52 25 63 1 2 35 7 9
归并排序后:
1 2 7 9 13 25 35 42 52 63