归并排序的核心就是分治,把大问题转换成小问题
照着算法导论,敲了一段代码,调了一下,这是适合自己用的,以后再要用到归并排序就懒得自己再想了,直接用这里的
C++版
using namespace std;
//这个函数是将两个已经排好序的数组转换成为一个数组
// a[p...q]和a[q+1...r]
void merge( int *a, int p, int q, int r ) {
int n1 = q - p + 1;
int n2 = r - q;
int left[n1], right[n2];
for ( int i = 0; i < n1; ++i ) {
left[i] = a[p+i];
}
for ( int i = 0; i < n2; ++i ) {
right[i] = a[q+1+i];
}
int i = 0;
int j = 0;
for ( int k = p; k <= r; ++k ) {
if( !(i < n1 && j < n2)) {
if( i >= n1 ) {
for ( ; k <= r; ++k ) {
a[k] = right[j++];
}
}
else {
for ( ; k <= r; ++k ) {
a[k] = left[i++];
}
}
break;
}
if( left[i] < right[j] ) {
a[k] = left[i++];
}
else {
a[k] = right[j++];
}
}
}
// 归并排序的主函数
void merge_sort(int *a, int p, int r) {
if ( p < r ) {
int q = ( p + r ) / 2;
merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge(a,p,q,r);
}
}
// test code
int main()
{
int a[] = {25,57,48,37,12,82,75,29,16};
//int a[] = {2,4,5,7,1,2,3,6};
for( int i = 0; i < 9; ++i ) {
cout<<a[i]<<' ';
}
cout<<endl;
merge_sort(a,0,8);
for( int i = 0; i < 9; ++i ) {
cout<<a[i]<<' ';
}
return 0;
}
输出结果
25 57 48 37 12 82 75 29 16
12 16 25 29 37 48 57 75 82
关于归并排序的分析见《算法导论》第二章
Java 版
public static void merge (int[] a, int s, int u, int v) {
LinkedList<Integer> l = new LinkedList<Integer>();
int i = s, j = u + 1;
while ( i <= u && j <= v ) {
if ( a[i] > a[j] ) {
l.add(a[j]);
j++;
}
else {
l.add(a[i]);
i++;
}
}
while ( i <= u ) {
l.add(a[i]);
i++;
}
while ( j <= v ) {
l.add(a[j]);
j++;
}
System.out.println(l);
i = s;
while ( !l.isEmpty() ) {
a[i] = l.poll();
i++;
}
}
public static void mergePass (int[] a, int t) {
int i = 0;
while ( i + 2*t <= a.length ) {
merge(a, i, i+t-1, i + 2*t -1);
i += (2 * t);
}
if ( i + t < a.length ) {
merge(a, i, i+t-1, a.length - 1);
}
}
public static void mergeSort (int[] a) {
int t = 1;
while ( t < a.length ) {
mergePass(a, t);
t *= 2;
if ( t <= a.length ) {
mergePass(a, t);
}
t *= 2;
}
}