【算法学习】归并排序——基于分治思想

归并排序的核心就是分治,把大问题转换成小问题

照着算法导论,敲了一段代码,调了一下,这是适合自己用的,以后再要用到归并排序就懒得自己再想了,直接用这里的

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;
		}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值