只是補個欠賬…
注意:
- 樹形結構切分到回覆,時間複雜度一般爲O(nlogn)
- 遞歸的歸併排序,最大時間複雜度=平均時間複雜度=O(nlogn)
- 遞歸的歸併排序是按照深度優先在樹上進行的。
僞碼描述:
MERGE_SORT(A,p,r)
//p<r時,至少還有兩個數字。
//當元素個數爲偶數,即p+r爲奇數時,(p+r)/2落在中線之前的那個元素。
if p<r then q<--(p+r)/2
//分解過程
MERGE-SORT(A,p,q)
MERGE-SORT(A,q+1,r)
//合併過程
MERGE(A,p,q,r)
MERGR(A,p,q,r)
n1<--q-p+1;n2<--r-q //n1爲左半部分元素個數,m2爲右半部分元素個數
create arrays L[1..n1] and R[1..n2]
for i<--1 to n1 do L[i]<--A[p+i-1]
for j<--1 to n2 do R[j]<--A[q+j]
i<--1;j<--1
for k<--p to r
do if L[i]<=R[j]
then A[k] == L[i]
i<--i+1
else A[k] == R[j]
j<--j+1
遞歸實現:
import java.util.Scanner;
public class 歸併遞歸實現 {
static void merge(int a[],int lb,int mid,int ub) {
int n1 = mid-lb+1;
int n2 = ub - mid;
int L[]=new int[n1+1];
int R[]=new int[n2+1];
for(int i=0;i<n1;i++) {
L[i]=a[lb+i];
}
for(int i=0;i<n2;i++) {
R[i]=a[mid+1+i];
}
L[n1]=R[n2]=Integer.MAX_VALUE;
int i=0,j=0;
for (int k=lb;k<=ub;k++) {
if(L[i]<=R[j]) {
a[k]=L[i];
i++;
}else {
a[k]=R[j];
j++;
}
}
}
static void mergeSort(int a[],int lb,int ub) {
if(lb<ub) {
int mid=(lb+ub)/2;
mergeSort(a,lb,mid);
mergeSort(a, mid+1, ub);
merge(a,lb,mid,ub);
}
}
public static void main(String args[]) {
Scanner sc=new Scanner(System.in);
int a[]=new int[100];
int k=sc.nextInt();
for(int i=0;i<k;i++) {
a[i]=sc.nextInt();
}
mergeSort(a, 0, k-1);
for(int i=0;i<k;i++) {
System.out.println(a[i]);
}
}
}