小和问题:
package com.xzy.study;
import java.net.SocketTimeoutException;
/**
* 归并排序练习题
* @author zjc
*/
public class Mergesort1 {
public static void main(String[] args) {
int [] arr = {1,3,4,2,5};
int res = process(arr,0,arr.length-1);
System.out.println(res);
// for (int i : arr) {
// System.out.println(i);
// }
}
/**
*递归调用
* @param arr:需要计算小和的数组
* @param l:左边位置
* @param r:右边位置
* @return 最终的小和
*/
public static int process(int [] arr,int l,int r){
if ( l < r) {
int midd = l + ((r - l) >> 1);
return process(arr,l,midd)+process(arr,midd+1,r)+mager(arr,l,midd,r);
}
return 0;
}
/**
* 计算小和
* @param arr:需要计算小和的数组
* @param l:左边位置
* @param midd:中间位置
* @param r:右边位置
* @return 小和的结果
*/
public static int mager(int [] arr, int l ,int midd , int r){
for (int c= l;c<=r;c++){
System.out.print(arr[c]+"\t");
}
System.out.print('\t'+"midd"+midd+"\t");
int[] help = new int[r - l + 1];
int i = 0;
int l1 = l;
int midd1 = midd + 1;
int sum = 0;
while (l1<=midd&&midd1<=r){
/*
(r - midd1 + 1):这一块相当于两边都在挪动,由于左右都排过序,左边第i个如果比右边第j个小则肯定比右边j+都小,
所以是arr[i]*(r-j+1)里面的j与题中的midd1相同。同理如果左边第i个比右边第j个大则需要比较
左边第i个和右边第j+1个的大小。
*/
int a=arr[l1]<arr[midd1]?(r - midd1 + 1) * arr[l1]:0;
System.out.print("a"+a+"\t");
sum +=a;
help[i++]=arr[l1]<arr[midd1]?arr[l1++]:arr[midd1++];
}
System.out.println();
while (l1<=midd){
help[i++]=arr[l1++];
}
while (midd1<=r){
help[i++]= arr[midd1++];
}
for (int j = 0;j<help.length;j++){
arr[j+l] = help[j];
}
return sum;
}
}