分治法之递归与二分查找
一、实验目的
1.了解分治法的思想;
2.掌握递归思想与程序编写
3.熟练使用二分查找实现代码编写。
二、实验内容
1.n!的递算法编写
package ch01;
import java.util.Scanner;
public class factorial {
public static int factorial(int n) {
if(n==0) return 1;
else return n*factorial(n-1);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.println(factorial(n));
}
}
2、无穷数列
1,1,2,3,5,8,13,21,34,55,…称为Fibonacci数列。
package ch01;
import java.util.Scanner;
public class fibonacci {
public static int fibonacci(int n) {
if(n<=1) return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.println(fibonacci(n-1));
}
}
运行结果
3、在给定一个n个元素的有序序列中查找与给定关键字x相同的元素具体位置。即输入一个n个元素的序列,其中n个元素从小到大的顺序排序,查找是否存在给定的值x(用二分查找法)
package ch01;
import java.util.Scanner;
public class binarySearch {
public static int binarySearch(int []a,int x,int n) {
int left=0;
int right=n-1;
while(left<=right)
{
int middle=(left+right)/2;
if(x==a[middle]) return middle;
if(x>a[middle]) left=middle+1;
else right=middle-1;
}
return -1;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("输入序列个数");
int n=scanner.nextInt();
int[] a = new int[n];
System.out.println("输入有序序列:");
for(int i=0;i<n;i++)
{
a[i]=scanner.nextInt();
}
System.out.println("输入要查找的数");
int x=scanner.nextInt();
System.out.println("要查找x的下标为:"+binarySearch(a, x, n));
}
}
运行结果
4.改写二分搜索算法:
设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于最小元素位置j.当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
package ch01;
import java.util.Scanner;
public class binarySearchDem {
public static int binarySearchDem(int []a,int x,int n) {
int left=0;
int right=n-1;
int i=0;
int j=0;
while(left<=right) {
int middle=(left+right)/2;
if(x==a[middle])
{
i=j=middle;
System.out.println("存在x,x的下标为:"+i);
return middle;
}
if(x>a[middle]) left=middle+1;
else {
right=middle-1;
}
}
i=right;
j=left;
System.out.println("不存在x,小于x的最大元素位置i为"+i+"大于x的最小位置j为"+j);
return -1;
}
public static void main(String[] args) {
Scanner scanner= new Scanner(System.in);
System.out.println("请输入数组的个数和要查找的数");
int n =scanner.nextInt();
int x =scanner.nextInt();
int []a=new int [n];
for(int i=0;i<n;i++) {
a[i]=scanner.nextInt();
}
binarySearchDem(a, x, n);
}
}
运行结果
5,。设X[0:n-1]和Y[0:n-1]为两个数组,每个数组中含有n个已排好序的数组,试设计一个O(logn)时间的算法,找出X和Y的2n个数的中位数。
package ch01;
import java.util.Scanner;
public class findmid {
public static double findmin(int []x,int []y,int x_low,int x_high,int y_low,int y_high) {
int x_mid;
int y_mid;
x_mid=(x_low+x_high)/2;
y_mid=(y_low+y_high)/2;
if (x_high - x_low== 0)//如果每个数组只有一个元素
return (x[x_low] + y[x_low])*1.0 / 2;
if (x_low == x_high)
return ((x[x_low] + y[y_low])*1.0/2);
//只有两个元素,也可以直接计算出两数组中位数
if((x_high-x_low)==1&&(y_high-y_low)==1)
{
return (max(x[x_low], y[y_low]) + min(x[x_high], y[x_high]))*1.0 / 2;
}
if ((x_low + x_high) % 2 == 0)
{
if (x[x_mid] > y[y_mid])
{
x_high = x_mid;
y_low = y_mid;
}
else if (x[x_mid] < y[y_mid])
{
x_low = x_mid;
y_high = y_mid;
}
else
return x[x_mid];
}
else
{
if (x[x_mid] > y[y_mid])
{
x_high = x_mid;
y_low = y_mid ;
}
else if (x[x_mid] < y[y_mid])
{
x_low = x_mid ;
y_high = y_mid;
}
else
return x[x_mid];
}
return findmin(x, y, x_low, x_high, y_low, y_high);
}
private static int min(int a, int b) {
if (a >= b)
return b;
else
return a;
}
private static int max(int i, int j) {
if (i >= j)
return i;
else
return j;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数组的个数:");
int n= scanner.nextInt();
System.out.println("请输入有序数组x和y:");
int []x=new int [n];
for(int i=0;i<n;i++) {
x[i]=scanner.nextInt();
}
int []y=new int [n];
for(int i=0;i<n;i++) {
y[i]=scanner.nextInt();
}
System.out.println("中位数为:"+findmin(x, y, 0, n, 0, n));
}
}
运行结果