
/*
* 二分查找算法
* 前提:数组必须有序
* 1.确定该数组的中间值下标 mid=(left+right)/2
* 2.让需要查找的数target和arr[mid]比较
*
* 非递归算法
* 递归算法
*/
public class BinarySearch_ {
public static void main(String[] args) {
int[] arr = {1,3,8,10,11,67,100};
int index = binarySearch(arr, 100);
int index2 = binarySearch(arr, 0, arr.length - 1, 100);
System.out.println("index=" + index);
System.out.println("index2=" + index2);
}
//二分查找非递归实现
//arr:查找数组(升序),target:查找数,返回对应下标,-1表示没有找到
public static int binarySearch(int[] arr,int target) {
int left = 0;
int right = arr.length - 1;
while(left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) {
return mid;
}else if (arr[mid] > target) {//向左查找
right = mid - 1;
}else {
left = mid + 1;
}
}
return -1;
}
//二分查找递归实现
//arr:数组,left:左边索引,right:右边索引,target:查找值,如果找到返回下标,没有返回-1
public static int binarySearch(int[] arr,int left,int right,int target) {
//当left > right时,说明没有找到
if (left > right) {
return -1;
}
int mid = (left + right) / 2;
int midVal = arr[mid];
if (target > midVal) {//向右递归
return binarySearch(arr, mid + 1, right, target);
}else if (target < midVal) {//向左递归
return binarySearch(arr, left, mid - 1, target);
}else {
return mid;
}
}
}
/*
* 分治算法
*
* 可以求解一些经典问题:
* 二分搜索
* 大整数乘法
* 棋盘覆盖
* 合并排序
* 快速排序
* 线性时间选择
* 最接近点对问题
* 循环赛日程表
* 汉诺塔
*
* 分治法在每一层递归上都有三个步骤
* 1.分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题
* 2.解决:若子问题规模较小而容易被解决则直接解决,否则递归解决各个子问题
* 3.合并:将各个子问题的解合并为原问题的解
*
* 分治算法解决汉诺塔问题
* 1.如果只有一个盘, A->C
* 2.如果有n>=2个盘,总是可以看作是两个盘(最下边的盘1,上面的所有盘2)
* 1.先把最上面的盘2,A->B
* 2.把最下边的盘1,A->C
* 3.把B的所有盘,B->C
*/
public class DivideAndConquer_ {
public static void main(String[] args) {
hanoiTower(5, 'A', 'B', 'C');
}
//分治算法
public static void hanoiTower(int num,char a,char b,char c) {
if (num == 1) {
System.out.println("第1个盘:" + a + "->" + c);
}else {
//1.先把最上面的盘2,A->B(中间使用C)
hanoiTower(num - 1, a, c, b);
//2.把最下边的盘1,A->C
System.out.println("第" + num + "个盘:" + a + "->" + c);
//3.把B的所有盘,B->C(中间使用A)
hanoiTower(num - 1, b, a, c);
}
}
}