分治算法是计算机五大常用算法之一,也是在JAVA编程中经常用到的算法之一。对于分治算法的理解,往往会停留在一些枯燥的概念上,比如“分而治之”,“问题原子分解”等。该文将会通过一个猜数字的游戏入手,引出对于分治算法基本思想的思考。
/**
* 猜数字游戏
*
* @author zhuhuix
* @date 2020-06-11
*/
public class Guess {
public static void main(String[] args) throws IOException {
int num = generateRandomInteger(1, 100);
int guessNum = 0;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("已生成一个【1-100】的整数,请开始猜数...");
while (num != guessNum) {
String s = bufferedReader.readLine();
if (!s.matches("[0-9]+")) {
System.out.println("请输入一个整数..");
continue;
}
guessNum=Integer.parseInt(s);
if (guessNum > 100 || guessNum < 1) {
System.out.println("请输入一个【1-100】整数..");
continue;
}
if (guessNum<num){
System.out.println("Sorry,比这个数字要大,请继续...");
}
if (guessNum>num){
System.out.println("Sorry,比这个数字要小,请继续...");
}
}
System.out.println("恭喜您猜中了!!!");
}
/**
* 产生一个在规定范围内的随机数
*
* @param left 起始数字
* @param right 终止数字
* @return 随机数
*/
private static int generateRandomInteger(int left, int right) {
Random random = new Random();
return left + random.nextInt(right - left + 1);
}
}
将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
归并排序就是一种典型的分治算法:将N个数字的一个大规模表分成1个数字的N个小规模表,再通过数字从小到大的顺序从1个数字的N个小规模表合并成N个数字的一个大规模表
/**
* 整型数组排序统一接口定义
*
* @author zhuhuix
* @date 2020-06-06
*/
public interface Sort <T extends Comparable<? super T>> {
/**
* 整型排序
* @param arr 待排序数组
*/
void sort(T[] arr);
}
/**
* 归并排序
*
* @author zhuhuix
* @date 2020-06-11
*/
public class MergeSort<T extends Comparable<? super T>> implements Sort<T> {
@Override
public void sort(T[] arr) {
mergeSort(arr,0,arr.length-1);
}
private void mergeSort(T[]arr,int l,int r){
// 递归退出条件:分到最小规模为止
if (r-l<=0){
return;
}
// 取到当前规模的中值
int mid = (l+r)/2;
// 中值的左边递归分解
mergeSort(arr,l,mid);
// 中值的右边递归分解
mergeSort(arr,mid+1,r);
// 排序合并
if (arr[mid].compareTo(arr[mid + 1]) > 0) {
merge(arr, l, mid, r);
}
}
private void merge(T[]arr,int l,int mid,int r){
T[]aux=Arrays.copyOf(arr,r-l+1);
for (int i = l; i <= r; i++) {
aux[i - l] = arr[i];
}
int i = l, j = mid + 1;
for (int k = l; k <= r; k++) {
if (i > mid) {
arr[k] = aux[j - l];
j++;
} else if (j > r) {
arr[k] = aux[i - l];
i++;
} else if (aux[i - l].compareTo( aux[j - l])<0) {
arr[k] = aux[i - l];
i++;
} else {
arr[k] = aux[j - l];
j++;
}
}
}
}
原文:https://www.cnblogs.com/zhuhuix/p/13098682.html