已知前序,中序,求后序
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是使该函数退出,进入下一个查找。
递归;
- 子问题须与原始问题为同样的事,且更为简单;
- 不能无限制地调用本身,
须有个出口,化简为非递归状况处理。
第一个代码将树不断化为小树,最后只剩下一个数据,再层层返回。
即要知道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)