【蓝桥集训】第六天——递归

作者:指针不指南吗
专栏:Acwing 蓝桥集训每日一题

或许会很慢,但是不可以停下来

文章目录

  • 1.树的遍历
  • 2.递归求阶乘
  • 3.求斐波那契数列

1.树的遍历

一个二叉树,树中每个节点的权值互不相同。

现在给出它的后序遍历和中序遍历,请你输出它的层序遍历。

输入格式

第一行包含整数 N,表示二叉树的节点数。

第二行包含 N 个整数,表示二叉树的后序遍历。

第三行包含 N 个整数,表示二叉树的中序遍历。

输出格式

输出一行 N 个整数,表示二叉树的层序遍历。

数据范围

1≤N≤30,
官方并未给出各节点权值的取值范围,为方便起见,在本网站范围取为 1∼N。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

4 1 6 3 5 7 2

  1. 知识点
  • 层序遍历:从上往下,从左往右一层一层遍历;

【蓝桥集训】第六天——递归_第1张图片

  • 中序遍历:先遍历左节点,再遍历根节点,最后遍历右节点;

  • 前序遍历:先遍历根节点,再遍历左节点,最后遍历右节点;

  • 后序遍历: 先遍历左节点,再遍历右节点,最后遍历根节点;

    【蓝桥集训】第六天——递归_第2张图片

  1. 推导树的原型过程

【蓝桥集训】第六天——递归_第3张图片

​ (1) 首先根据后序遍历的最后一个数,来确定根节点,在中序遍历中找到相同的数即根节点;

​ (2) 由根节点在中序遍历中的位置,我们可以推出来,左子树长度,右子树长度,对应的在后序遍历中找到;

​ (3) 再根据后序遍历中左子树的最后一个,即左子树的根节点,…,递归

  • 最后需要层序遍历:

    我们可以先开一个vector,第一层放在 vector[ 0 ] 里面,第二层放在vector[1]里面…

  1. 代码实现

    #include
    using namespace std;
    
    const int N=35;
    int a[N],b[N],p[N];  
    int n;
    
    vector<int> level[N]; //每一层用一个vector来存数值,因为我们要层序遍历输出;
    
    void build(int al,int ar,int bl,int br,int d) //d表示树的层数;
    {
        if(al>ar) return ;   // 当al>ar时,说明,已经递归到最后一个子树;
        int val=a[ar];  //每个子树的根节点就是后续遍历的最后一个数字,用val存下来;
        level[d].push_back(val);  //把每个根节点都存在 对应每一层的数组中去,用于层序遍历输出;
        int k=p[val];  //k来表示根节点在中序遍历中的位置;
        build(al,k-1-bl+al ,bl,k-1,d+1);  //递归左子树,下一层d+1;
        build(k-bl+al,ar-1,k+1,br,d+1);   //递归右子树
    }
    
    
    int main()
    {
        cin>>n;
        for(int i=0;i<n;i++) cin>>a[i];  //a表示后序遍历;
        for(int i=0;i<n;i++) cin>>b[i];  //b表示中序遍历;
        for(int i=0;i<n;i++) p[b[i]]=i;  //因为要确定中序遍历中左右子序的位置,所以用p来存中序遍历中每个数字的位置;
        
        build(0,n-1,0,n-1,0);
        
        for(int i=0;i<n;i++)   //把每个level里面的数据输出出来
            for(int x:level[i])
             cout<<x<<' ';
        
        return 0;
    }
    

    补充

    build的函数参数的表示如下图:

    后序遍历中左子树的ar 的计算,列个方程即可,如下图:

    【蓝桥集训】第六天——递归_第4张图片

2.递归求阶乘

请使用递归的方式求 n 的阶乘。

输入格式

共一行,包含一个整数 n。

输出格式

共一行,包含一个整数,表示 n 的阶乘的值。

数据范围

1≤n≤10

输入样例:

3

输出样例:

6
  • 代码实现

    #include
    using namespace std;
    
    int fac(int n)
    {
    	if(n==1) return 1;
    	else return fac(n-1)*n;
    }
    
    int main()
    {
    	int n;
    	cin>>n;
    	int k=fac(n);
    	cout<<k;
    	return 0;
     } 
    

3.求斐波那契数列

请使用递归的方式求斐波那契数列的第 n 项,下标从1开始。

斐波那契数列:1,1,2,3,5…这个数列从第 3 项开始,每一项都等于前两项之和

输入格式

共一行,包含整数 n。

输出格式

共一行,包含一个整数,表示斐波那契数列的第 n� 项。

数据范围

1≤n≤30

输入样例:

4

输出样例:

3
  • 代码实现

    #include
    using namespace std;
    
    int fun(int n)
    {
        if(n<=2) return 1;
        else return fun(n-1)+fun(n-2);
    }
    
    int main()
    {
        int n;
        cin>>n;
        cout<<fun(n);
        return 0;
    }
    

虽然跟着y总学习,但是简单题也要回顾
Alt

你可能感兴趣的:(Acwing,蓝桥集训每日一题,算法,数据结构,图论)