递归

已知前序,中序,求后序

package a;
import java.util.Scanner;
public class BBBB {
	public static class Tree{
		public int value;
		public Tree left;
		public Tree right;
		public Tree(int value) {
			this.value=value;
		}
	}
	public static void main(String[] args){
		Scanner sc=new Scanner(System.in);
				int n=sc.nextInt();
				Scanner ec=new Scanner(System.in);
		String inputString = ec.nextLine();
        String stringArray[] = inputString.split(" ");
        int[]preOrder=new int[n];
		int[]midOrder=new int[n];
        for (int i = 0; i < stringArray.length; i++) 
        	preOrder[i] = Integer.parseInt(stringArray[i]);
        String inputString2 = ec.nextLine();
        String stringArray2[] = inputString2.split(" ");
        	for (int i = 0; i < stringArray2.length; i++) 
        		midOrder[i] = Integer.parseInt(stringArray2[i]);
		getBehindOrder(preOrder, midOrder);
	}
	public static void getBehindOrder(int[]pre,int[]mid){
		if (pre==null||mid==null||pre.length!=mid.length) {
			return;
		}
		Tree root=buildTree(pre, mid);
		behindOrder(root);
	}
	
	public static void behindOrder(Tree root){//�������������
		if (root==null) {
			return;
		}
		if (root.left!=null) {
			behindOrder(root.left);
		}
		if (root.right!=null) {
			behindOrder(root.right);
		}
		System.out.print(root.value+" ");
		
	}
	public static Tree buildTree(int[]preOrder,int[]midOrder){//����ǰ������򣬽���������
		int value=preOrder[0];
		int length=preOrder.length;
		Tree root=new Tree(value);
		root.left=root.right=null;
		if (preOrder.length==1) {
			return root;
		}
		int index=0;
		while(midOrder[index]!=value)
			index++;//�˴���Ҫ����index==length-1�����
		if (index>0) {
			//�����У����ڵ���ߵĽڵ㶼����������
			int[]leftSubPreOrder=new int[index];
			for(int i=0;i<leftSubPreOrder.length;i++){
				leftSubPreOrder[i]=preOrder[i+1];
			}
			int[]leftSubMidOrder=new int[index];
			for(int i=0;i<leftSubMidOrder.length;i++){
				leftSubMidOrder[i]=midOrder[i];
			}
			root.left=buildTree(leftSubPreOrder, leftSubMidOrder);
		}
		
		
		if(length-index-1>0){
		int[]rightSubMidOrder=new int[length-index-1];
		for(int i=0;i<rightSubMidOrder.length;i++){
			rightSubMidOrder[i]=midOrder[i+index+1];
		}
		int[]rightSubPreOrder=new int[length-index-1];
		
		for(int i=0;i<rightSubPreOrder.length;i++){
			rightSubPreOrder[i]=preOrder[i+index+1];
		}
		
		root.right=buildTree(rightSubPreOrder, rightSubMidOrder);
		}
		return root;
	}
}
package A1;
import java.util.Scanner;

public class Main {//注意蓝桥在提交代码时,主函数名必须是Main
	public static void main(String[] args) {
		int x;
		int data[] = new int [200];
		for (int i=0; i<200; i++)
			data[i]=4*i+6;
		Scanner sc = new Scanner(System.in);
		x=sc.nextInt();
		int t = BinaryFind(data,x,0,199);
		System.out.println(t);
	}
	//数组名、带查找元素,左边界,右边界
	//脑子里面可以画画图
	public static int BinaryFind(int a[],int x,int left,int right) {
//		if(left>right) return -1;
		int middle=(left+right)/2;
		if(x==a[middle]) 
		{
			return middle;
		}
		else if(x<a[middle])
		{
			return BinaryFind(a, x,left, middle-1);
		}
		else if(x>a[middle])
		{
			return BinaryFind(a, x, middle+1,right);
		}
		return -1;
	} 
}

这里的return是使该函数退出,进入下一个查找。

递归;

  1. 子问题须与原始问题为同样的事,且更为简单;
  2. 不能无限制地调用本身,在这里插入图片描述
    须有个出口,化简为非递归状况处理。

第一个代码将树不断化为小树,最后只剩下一个数据,再层层返回。
即要知道A的tree 需知Btree,须知B,又得G,G的结构为左右都空作为返回条件。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
思路:
是否可以递归?当前问题可以划分成一个相同的更小的子问题,则可以
1.重复:每一步都是当前数组的第一个元素加剩下的数组元素(相同子问题)
2.找变化:数组剩下的量变小是毋庸置疑的,关键是初始数组的下标在后移
3.出口:剩下最后一个只有一个元素的数组的和是已知的。

字符串翻转:
在这里插入图片描述
思路和我的不一样,我的是想用头和尾交换进行递归,(这是错误的)而这是用尾直接和前面的字符组交换进行递归。

在这里插入图片描述

裴波那切数列
在这里插入图片描述
在这里插入图片描述
把函数的定义写在了main函数里了
在这里插入图片描述
利用堆栈消耗大量内存来减少代码量,之间的代码的变量仍在堆栈里面,和自己创建数组存储一个道理,直到出现已知量再层层返回
本来返回的是F(N),但他等于子问题f(n-1)+f(n-2),于是返回f(n-1)+f(n-2),变成子问题,再层层往下,直到出现已知量。

在这里插入图片描述
在这颗树上,有重复的运算,左边在求F(5)时需要求F(4),而右边f(4)和f(5)是同一级的,这里,出现了反复求解,需要优化。

辗转相除法求最大公约数
public int a(int m,int n) {
if(m%n==0)
return n;
return a(n,m%n);
}

这里的return 必须要写的,因为这个函数要返回下次调用的返回值,层层套。还是那个原理,做一部分,剩下的留给同样格式的子问题去做,这里就是要返回公约数,那最后一个语句就必须要返回值,虽然真正计算得出值得是第一条语句。

在这里插入图片描述

在这里插入图片描述

可以用递归表达式的思路 如

f(n)=f(n/2)+0(n) 不断下楼梯,设x为层数,当下到分f(1)时 2^ x-1=n ,x-1= lg2n
f(n)=f(n-1)+f(n-2)+f(n-3)

例子:
题目:小白走楼梯:小白正在上楼梯,总共有n阶楼梯,她总共可以有三种方式,一次上阶,两节楼梯,或者三阶。问:如果要走完n阶楼梯,一共有多少种走法。

思路:递归的方法。 倒着来思考,假设他现在站在最顶层,他每一次只能有三种方案,
一次一阶,两阶,三阶,而这些方案加起来,等于他上的总阶数,即:
f(n)=f(n-1)+f(n-2)+f(n-3),表达式和斐波拉契数列的表达式看起来很像,思路也有些
类似,这个问题有三个分支,算法的复杂度是O(3^n)。

public class XBZLT {
	static int zs=0;
	public static void main(String[] args) {
		int b=4;
		a(b);
		System.out.print(zs);
	}

	static void  a(int n) {
		if(n==0)  return;
		if()
		if(n>=3) {
			a(n-3);
			a(n-2);
			a(n-1);
		}
		else if(n==2) {
			
			a(n-2);
			a(n-1);
		}
		else a(n-1);
	}
}
//过程思维,不太好,在2才是体现了递归的思维。分为子问题,找出口
public class XBZLT2 {
	public static void main(String[] args) {
		System.out.print(a(5));
	}
	static int a(int n) {
		if(n==1) return 1;
		if(n==2) return 2;
		if(n==3) return 4;
				
		return a(n-1)+a(n-2)+a(n-3);
	}

}
第二段代码才是体现了递归的思维,可以将一个大问题分解成小问题,可知,这是可以写成递归表示式的

在这里插入图片描述

这个也要将文字表达的意思抽象成数学模型,所以做题思维方式很重要 1 1 2 3 5 8 13 类似今天的五种解题思路,这列举出来是有规律的 f(n)=f(n-1)+f(n-2) 以为关系是传递过去的,很自然很可能有这种关系,因为分f(3)=f(2)+f(1),因为能生的就恰好等于与他隔三个月的兔子的个数,而与他隔三个月的兔子个数又恰好等于f(n-2)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值