考虑K阶变系数线性递推方程:

现给定初值a1,a2,—,ak和n>k,要求编程打印an,an-1,—,ak+1的值

该问题用常规的迭代法非常容易解决,现在要考虑的是用遍历递归调用树的方法求解。n=7,k=3时,递归调用树为

package programm;           //遍历递归树中所有节点,相同值会重复计算
import java.util.*;public class RecursionTree
{public static void main(String[] args){final int K=3;final int N=7;int[] initial=new int[K];for (int i=0; i<K; i++)initial[i]=i+1;Stack<Node> stack=new Stack<Node>();stack.push(new Node(0, 0, N));boolean TF=true;int sign=0, n=stack.getTop().getIndex();while(!stack.isEmpty()){if (1<=n&&n<=K){stack.getTop().setSum(stack.getTop().getSum()+initial[n-1]*(stack.getTop().getIndex()+stack.getTop().getFlag()));TF=false;n=stack.getTop().getIndex();}else{ if (TF==false){stack.getTop().setFlag(stack.getTop().getFlag()+1);if (stack.getTop().getFlag()>K){Node temp=stack.pop();temp.setSum(temp.getSum()+temp.getIndex());if (stack.isEmpty()){System.out.println("The "+temp.getIndex()+"nd item is "+temp.getSum());}else{                if (stack.getTop().getFlag()==1 && temp.getIndex()>sign){sign=temp.getIndex();System.out.println("The "+temp.getIndex()+"nd item is "+temp.getSum());}stack.getTop().setSum(stack.getTop().getSum()+temp.getSum()*(stack.getTop().getIndex()+stack.getTop().getFlag()));n=stack.getTop().getIndex();TF=false;}}else{if ((n=stack.getTop().getIndex()-stack.getTop().getFlag())>K){stack.push(new Node(0, 0, n));TF=true;}else{continue;}}}else{stack.getTop().setFlag(stack.getTop().getFlag()+1);if ((n=stack.getTop().getIndex()-1)>K){stack.push(new Node(0, 0, n));TF=true;}else{continue;}}}}}}class Node
{private int sum;private int flag;private int index;    public Node(int sum, int flag, int index){this.sum=sum;this.flag=flag;this.index=index;}public int getSum(){return sum;}public void setSum(int sum){this.sum=sum;}public int getFlag(){return flag;}public void setFlag(int flag){this.flag=flag;}public int getIndex(){return index;}
}class Stack<E>
{ArrayList<E> list=new ArrayList<E>();public boolean isEmpty(){return list.isEmpty();    }public int getSize(){return list.size();}public E getTop(){return list.get(getSize()-1);}public E pop(){E interval=list.get(getSize()-1);list.remove(getSize()-1);return interval;}public void push(E Ob){list.add(Ob);}
}

运行结果:

以上方法的问题是,相同的项会被重复计算多次,如a4被重复计算了三次,所以以上方法需要改进。用数组保存已求出项的值,遍历
到相同项时直接从数组中找到并使用其值即可。要实现这一点,需要修改源程序41行,48行,60-61行。修改后的代码如下:
程序二:

package programm;   //不遍历递归树中所有节点,相同值不会重复计算
import java.util.*;public class RecursionTree
{public static void main(String[] args){final int K=3;   //递推方程阶数final int N=7;   //要求的部分数列中下标最大的项的下标int[] initial=new int[K];   //初值a1----akfor (int i=0; i<K; i++)    //令初值a1----ak分别为1,2---,kinitial[i]=i+1;Stack<Node> stack=new Stack<Node>();   //建立Node类型栈对象stack.push(new Node(0, 0, N));     //递归树根节点压入栈,该节点flag=sum=0,index=Nboolean TF=true;    //true向前进至下一层,false回溯至上一层int sign=0, n=stack.getTop().getIndex();   //sign记录当前已遍历节点中下标最大的节点,n初始化为根节点下标int[] result=new int[N-K];   //记录ak+1---aN项值的数组while(!stack.isEmpty())   //栈不空{if (1<=n&&n<=K)  //到达递归树中可直接写出值的叶子结点{stack.getTop().setSum(stack.getTop().getSum()+initial[n-1]*(stack.getTop().getIndex()+stack.getTop().getFlag()));  //将叶子结点值乘以系数累加至父节点TF=false;n=stack.getTop().getIndex();    //回溯}else{ if (TF==false){stack.getTop().setFlag(stack.getTop().getFlag()+1);   //当前节点flag增一,试探下一子节点if (stack.getTop().getFlag()>K)    //当前节点所有子节点均试探完毕{Node temp=stack.pop();   //从栈中弹出当前节点temp.setSum(temp.getSum()+temp.getIndex());   //加上尾数f(n),得到当前节点的值if (stack.isEmpty())  //栈空,temp引用根节点,根节点值已求出,存放在temp的sum中{result[N-K-1]=temp.getSum();   //在数组result中存放根节点即aN的值System.out.println("The "+temp.getIndex()+"nd item is "+temp.getSum());  //打印aN的值}else{                if (stack.getTop().getFlag()==1 && temp.getIndex()>sign)  //找到当前已遍历节点中下标最大节点{sign=temp.getIndex();   //设置新的最大下标result[temp.getIndex()-K-1]=temp.getSum();  //当前节点值存放至result数组中System.out.println("The "+temp.getIndex()+"nd item is "+temp.getSum());  //打印当前节点值}stack.getTop().setSum(stack.getTop().getSum()+temp.getSum()*(stack.getTop().getIndex()+stack.getTop().getFlag()));  //当前节点值乘以系数累加至父节点n=stack.getTop().getIndex();TF=false;  //回溯}}else{if ((n=stack.getTop().getIndex()-stack.getTop().getFlag())>K)  //前进至非叶子结点{stack.getTop().setSum(stack.getTop().getSum()+result[n-K-1]*(stack.getTop().getIndex()+stack.getTop().getFlag()));  //当前节点值之前已算出,从数组result中找出该值乘以系数累加至父节点n=stack.getTop().getIndex();TF=false;      //回溯}else{continue;  //直接进至下一轮循环,累加叶子节点值和系数乘积至父节点}}}else{stack.getTop().setFlag(stack.getTop().getFlag()+1); //进至新的一层,当前节点flag增一试探下一层节点if ((n=stack.getTop().getIndex()-1)>K) //下一层第一个节点非叶子{stack.push(new Node(0, 0, n));    //该节点压入栈TF=true;  }                                      else{continue;    //同上}}}}}}class Node    //递归树节点类
{private int sum;     //当前节点值private int flag;    //当前节点的父节点下标和当前节点下标之差private int index;    //当前节点下标public Node(int sum, int flag, int index)   //构造方法{this.sum=sum;this.flag=flag;   this.index=index;}public int getSum(){return sum;}public void setSum(int sum){this.sum=sum;}//访问器和修改器public int getFlag(){return flag;}public void setFlag(int flag){this.flag=flag;}public int getIndex(){return index;}
}class Stack<E>            //泛型栈类
{ArrayList<E> list=new ArrayList<E>();public boolean isEmpty(){return list.isEmpty();    }public int getSize(){return list.size();}public E getTop(){return list.get(getSize()-1);}public E pop(){E interval=list.get(getSize()-1);list.remove(getSize()-1);return interval;}public void push(E Ob){list.add(Ob);}
}

可以验证运行结果和程序一相同,但是节省了运行时间
删掉程序一37行,修改24行和51行可以得到程序三,用于计算递推数列an=an-1+—an-kn>k a1=1—ak=k当给定n>k时an,—,ak+1的值。
程序三(n=7, k=2, a1=1, a2=2):

package programm;          //an=an-1+---an-k型递归式求解,遍历所有节点
import java.util.*;public class RecursionTree
{public static void main(String[] args){final int K=2;final int N=7;int[] initial=new int[K];for (int i=0; i<K; i++)initial[i]=i+1;Stack<Node> stack=new Stack<Node>();stack.push(new Node(0, 0, N));boolean TF=true;int sign=0, n=stack.getTop().getIndex();while(!stack.isEmpty()){if (1<=n&&n<=K){stack.getTop().setSum(stack.getTop().getSum()+initial[n-1]);TF=false;n=stack.getTop().getIndex();}else{ if (TF==false){stack.getTop().setFlag(stack.getTop().getFlag()+1);if (stack.getTop().getFlag()>K){Node temp=stack.pop();if (stack.isEmpty()){System.out.println("The "+temp.getIndex()+"nd item is "+temp.getSum());}else{                if (stack.getTop().getFlag()==1 && temp.getIndex()>sign){sign=temp.getIndex();System.out.println("The "+temp.getIndex()+"nd item is "+temp.getSum());}stack.getTop().setSum(stack.getTop().getSum()+temp.getSum());n=stack.getTop().getIndex();TF=false;}}else{if ((n=stack.getTop().getIndex()-stack.getTop().getFlag())>K){stack.push(new Node(0, 0, n));TF=true;}else{continue;}}}else{stack.getTop().setFlag(stack.getTop().getFlag()+1);if ((n=stack.getTop().getIndex()-1)>K){stack.push(new Node(0, 0, n));TF=true;}else{continue;}}}}}}class Node
{private int sum;private int flag;private int index;    public Node(int sum, int flag, int index){this.sum=sum;this.flag=flag;this.index=index;}public int getSum(){return sum;}public void setSum(int sum){this.sum=sum;}public int getFlag(){return flag;}public void setFlag(int flag){this.flag=flag;}public int getIndex(){return index;}
}class Stack<E>
{ArrayList<E> list=new ArrayList<E>();public boolean isEmpty(){return list.isEmpty();    }public int getSize(){return list.size();}public E getTop(){return list.get(getSize()-1);}public E pop(){E interval=list.get(getSize()-1);list.remove(getSize()-1);return interval;}public void push(E Ob){list.add(Ob);}
}

运行结果:

 显然,所求得的即为斐波那契数列的第4-8项
为了便于读者理解程序一二三,下面给出一个经过简化的程序四,实现思想和程序一二三基本相同且功能和程序三相同
程序四(n=7, k=2, a1=1, a2=2):不难验证运行结果和程序三是一致的

package RecursionTree;    //简化版的an=an-1+---an-k型递归式求解,遍历所有节点
import java.util.*;public class recursiontree
{public static void main(String[] args) {final int K=2;final int N=7;int[] initial=new int[K];for (int i=0; i<K; i++)initial[i]=i+1;Stack<Node> stack=new Stack<Node>();stack.push(new Node(0, N));boolean TF=true;int sum=0;while (!stack.isEmpty()){if (1<=stack.getTop().getIndex() && stack.getTop().getIndex()<=K){sum+=initial[stack.getTop().getIndex()-1];stack.pop();TF=false;}else{if (TF==false){stack.getTop().setFlag(stack.getTop().getFlag()+1);if (stack.getTop().getFlag()>K){stack.pop();TF=false;}else{stack.push(new Node(0, stack.getTop().getIndex()-stack.getTop().getFlag()));TF=true;}}else{stack.getTop().setFlag(stack.getTop().getFlag()+1);stack.push(new Node(0, stack.getTop().getIndex()-1));TF=true;}}}System.out.println("The "+N+"nd item is "+sum);}
}class Node
{private int flag;private int index;    public Node(int flag, int index){this.flag=flag;this.index=index;}    public int getFlag(){return flag;}public void setFlag(int flag){this.flag=flag;}public int getIndex(){return index;}
}class Stack<E>
{ArrayList<E> list=new ArrayList<E>();public boolean isEmpty(){return list.isEmpty();    }public int getSize(){return list.size();}public E getTop(){return list.get(getSize()-1);}public E pop(){E interval=list.get(getSize()-1);list.remove(getSize()-1);return interval;}public void push(E Ob){list.add(Ob);}
}

遍历递归树求递推数列通项相关推荐

  1. 3a2b递归排列java,高考数学解题技巧-递推数列通项公式的十种策略例析

    求递推数列通项公式的十种策略例析 递推数列的题型多样,求递推数列的通项公式的方法也非常灵活,往往可以通过适当的策略将问题化归为等差数列或等比数列问题加以解决,亦可采用不完全归纳法的方法,由特殊情形推导 ...

  2. [线性代数学习笔记] 线性递推数列及 Berlekamp-Massey 算法的详细推导过程

    线性递推数列 线性递推 对于无限数列 {a0,a1,...}\{a_0,a_1,...\}{a0​,a1​,...} 和有限非空数列 {r0,r1,...,rm−1}\{r_{0},r_1,...,r ...

  3. 线性递推数列_学习笔记

    前置知识:线代基础(越多越好 发现了一位老哥写的笔记,精炼得相当到位 (这是博客地址嗷) . 线性递推数列 基本性质 定理1.1. 对于无限数列 { a 0 , a 1 , a 2 . . . } \ ...

  4. 【学习笔记】线性递推数列

    1.11.11.1 定义:对于无限数列{a0,a1,a2,...}\{a_0,a_1,a_2,...\}{a0​,a1​,a2​,...}和有限非空数列{r0,r1,r2,...,rm−1}\{r_0 ...

  5. a(n+1) = f[a(n)] 型递推数列的迭代作图(玩计算器玩出了问题)

    把任意一个正数开平方再加 \(1\), 把得到的结果也开平方再加 \(1\), 不断算下去,最终总会得到 \( \frac{3+\sqrt{5}}{2} \approx 2.61804 \), 即: ...

  6. 51Nod-1126 求递推序列的第N项【递推序列+模除】

    1126 求递推序列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * ...

  7. 有理展开定理与递推数列通项公式

    可以结合 https://blog.csdn.net/ez_lcw/article/details/125731258?spm=1001.2014.3001.5502. 不同根的有理展开定理 设 R ...

  8. Loj 538 递推数列

    Loj 538 递推数列 出题人:这题提高难度吧.于是放在了%你赛的 \(D1T2\) . 递推式为 \(a_i=k*a_{i-1}+a_{i-2}\) , 注意到 \(k\in \mathbb{N_ ...

  9. 如何用递归树求快速排序时间复杂度

    其实也就是点看算法导论的心得,感觉算法导论写的有点不详细的补充 快速排序 我的理解就是利用分治法 ,递归排序最后合并的排序,因为快速排序的最坏时间复杂度比较低所以快速被叫做快速排序如图 对于求快速排序 ...

最新文章

  1. 论前端工程师如何应对西电教学评估系统
  2. RS232交叉串口线的做法与测试!
  3. c语言中成绩等级流程图画法,大家帮我看看这个程序的流程图怎么画,谢了
  4. 自学python什么时候能够兼职-我,做设计两年,工资4000,兼职1.5w...
  5. matlab 基于GUI的PID研究
  6. 使用Synergy多台电脑共享键盘鼠标和剪贴板
  7. 猴子选大王--约瑟夫问题浅析
  8. 【C#学习笔记】单精度和双精度浮点型操作留意。
  9. php操作cookie_php设置cookie【三种方案】
  10. 测评盘点2021十大淘宝购物优惠券app,高省是一个怎样的角色?
  11. 汇编语言编译文件报 error A2105: Excepted: instruction or directive
  12. 8-08双重循环--九九乘法表
  13. python是动态语言图片_利用python图片生成,需10几行代码,生成的动态表情包(小黄鸭)...
  14. 使用pandas对excel表格筛选
  15. three.js快速入门和实战
  16. select下拉框选择触发事件
  17. 【方向盘】因“双减”失业,厉经9面,终获美团外卖L8的Offer
  18. 从市场应用角度上来划分,云可分为文件云、应用云、手机云和开放云
  19. ciscn_2019_en_2
  20. 批量修改文件名的软件

热门文章

  1. 靶机渗透练习56-digitalworld.local:TORMENT
  2. 高速数据采集记录存储回收卡
  3. android webview加载html图片自适应手机屏幕大小点击查看大图
  4. python信号处理教程_python玩转信号处理与机器学习入门
  5. 2020信创产业独角兽100强:中兴新支点国产操作系统位列第6
  6. 顺序表的插入和删除操作
  7. 中兴ZTE ZXR10-3928A配置端口镜像
  8. Merry Christmas——用shell 脚本实现画一个 blingbling 的圣诞树
  9. 安装Oracle提示:[INS-35206] 目录已在使用
  10. 反射Field类的学习