您的位置:首页 > 其它

学习算法导论-合并排序

2009-09-21 08:31 363 查看
采用分治模式处理,将n个数据分为n/2的两块,递归的处理每个块(同样是分治模式),然后合并结果(合并过程为比较两块,将最小的数据放入数组中即可。

  先奉上我自己先写的方法,该方法有很大的问题

/**
* 我自己的merge,这是个奇怪的解法。
* MergeSort这个方法最大的毛病就在于将递归和处理放在一起了。实际上可以先递归,然后再处理。
* 合并排序
* @param A int[]
*/
private void MergeSort(int[] A) {
int n = A.length;
int n1 = n / 2;
int n2 = n - n1;
if (n != 1) {
int[] L = new int[n1];
int[] R = new int[n2];
for (int i = 0; i < n1; i++) { //初始化分块
L[i] = A[i];
}
for (int i = 0; i < n2; i++) {
R[i] = A[n1 + i];
}
MergeSort(L);
MergeSort(R);
int[] newL = new int[n1 + 1]; //真恶。
int[] newR = new int[n2 + 1];
setArray(newL, L);
setArray(newR, R);
int i = 0; //游标i
int j = 0; //游标j
for (int k = 0; k < A.length; k++) {
if (newL[i] < newR[j]) {
A[k] = newL[i];
i += 1;
} else {
A[k] = newR[j];
j += 1;
}
}
}

}


发现,这哪是原地排序啊。

看看新的合并排序吧:

public void sort() {
int[] A = new int[] {5, 7, 9, 3, 6, 2, 1, 4, 8}; //所有的数都是唯一的.
mergeSort(A,0,A.length-1);
int n = A.length;
for (int i = 0; i < n; i++) {
System.out.print(A[i] + (i == n - 1 ? "" : ","));
}

}
private void mergeSort(int[] A,int start,int last){
if(start<last){
//分解
int middle = (last + start) / 2; //取中值
//解决
mergeSort(A, start, middle); //前半部分排序
mergeSort(A, middle + 1, last); //后半部分排序
//合并
merge(A, start, middle, last);//处理合并。
}
}
private void merge(int[] A,int start,int middle,int last){
int n1 = middle - start+1;
int n2 = last - middle;
int[] L = new int[n1];
int[] R = new int[n2];
for (int i = 0; i < L.length; i++) {
L[i] = A[start+i];
}
for (int i = 0; i < R.length; i++) {
R[i]  = A[middle+i+1];
}
int Lpoint = 0;
int Rpoint = 0;
for (int i = start; i <=last; i++) {
int LValue =( Lpoint==n1?Integer.MAX_VALUE:L[Lpoint]);
int RValue =( Rpoint==n2?Integer.MAX_VALUE:R[Rpoint]);
if(LValue<RValue){
A[i] = LValue;
Lpoint+=1;
}else{
A[i]=RValue;
Rpoint+=1;
}
}
}


典型的分治法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: