归并算法
更正一下,昨天的那个图解,
有最后一个地方,应该这样说,将子数组划分到最后是时刻时(即一个子数组只有一个数时)并不有序【其实两个数字之间肯定是一大一小或相等,逻辑上是有序的,只不过大小的方向不一样罢了】,
在归并子数组时才是按顺序那拿会的。
好的,因为昨天的只是讲一个归并的思想,所以要将数组的两个子数组排好顺序。今天的代码就不一样了!!
归并算法最重要的分治思想今天来了。。
话不多说!!上代码!
//归并算法
/*
归并算法最主要的就是递归调用,(即:在方法的自身调用自身)
写一个简单的递归调用的伪代码:
public static void main(String args[]){
System.out.printin(f(10));
}
static long f(int n){
if(n<1)return -1;
if(n==1)return 1;
return n+f(n-1);//递归调用了自身方法。
}
归并排序的思想就是:如果一个数组无序,那么 ,将这个数组一分为二,
如果一分为二的数组还是无序的,那么就继续往下分数组,直到分出来的数组有序
(一般情况下,被分的数组只剩两个数,那么这两个数一定有序)
*/
package sdx;
public class Main10 {
public static void main(String[] args) {
// 前提是两个子数组已经排好顺序了
int a[] = {56,78,789,3,890,66,73,547,67,8,54,7546,23};
sort(a, 0, a.length-1);
print(a);
}
//分治思想
static void sort(int a[],int left,int right) {
if(left==right){
return;
}
if(left>right){
System.out.println("你输入的是什么几把玩意儿?");
return;
}
// System.out.println(left);
// System.out.println(right);
//分成两半,,找中间值
int mid=left+(right-left)/2;
//左排序
sort(a,left,mid);
//右边排序
sort(a,mid+1,right);
merge(a, left, mid+1, right);
}
//归并思想
static void merge(int a[], int leftPtr, int rightPtr, int rightBound) {
// 将数组从中间断开
int mid = rightPtr-1;
// 分配辅助空间
int temp[] = new int[rightBound - leftPtr + 1];
// i=0指在前半个数组的第一个位置1
// j=min+1指在后半截数组的第一个位置上3
// k=0指在temp的第一个位置上
int i = leftPtr, j = rightPtr, k = 0;
while (i <= mid && j <= rightBound) {
temp[k++] = a[i] <= a[j] ? a[i++] : a[j++];// 就一句话
}
while (i <= mid)
temp[k++] = a[i++];
while (j <=rightBound)
temp[k++] = a[j++];
for(int m=0;m<temp.length;m++){
a[leftPtr+m]=temp[m];
}
}
static void print(int arr[]) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}