递归题目

递归题目
递归题目

例题

计算n的阶乘

#include

int factorial(int n)

{

int result;

if (n<0) //判断例外

{

printf("输入错误!\n");

return 0;

} else if (n==0 || n==1)

{

result = 1; //回推墙

}

else

{

result = factorial(n-1) * n; //递推关系,这个数与上一个数之间的关系。

}

return result;

}

int main(){

int n = 5; //输入数字5,计算5的阶乘

printf("%d的阶乘=%d",n,factorial(n));

return 0;

}

程序在计算5的阶乘的时候,先执行递推,当n=1或者n=0的时候返回1,再回推将计算并返回。由此可以看出递归函数必须有结束条件。

递归函数特点:

1. 每一级函数调用时都有自己的变量,但是函数代码并不会得到复制,如计算5的阶乘时每递推一次变量都不同;

2. 每次调用都会有一次返回,如计算5的阶乘时每递推一次都返回进行下一次;

3. 递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序;

4. 递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反;

5. 递归函数中必须有终止语句。

一句话总结递归:自我调用且有完成状态。

例题

小明为了学好英语,需要每天记单词,第一天记1个,第二天记2个依次类推,请用代码完

成,算出小明第10天开始的时候会了多少个单词?

分析:

回推墙是“第一天记1个”

递推关系是“第n天记的单词= 第n-1天记的单词数量+n"

#include

/* 定义获取单词数量的函数*/

int getWordNumber(n)

{

if(n == 1)

{

return 1; //回推墙

}

else{

return getWordNumber(n-1)+n ; //递推关系

}

}

int main()

{

int num = getWordNumber(10); //获取会了的单词数量

printf("小明第10天记了:%d个单词。\n", num);

return 0;

}

例题

有5个人坐在一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第3个人,又说比第2人大两岁。问第2个人,说比第1个人大两岁。最后问第1个人,他说是10岁。请问第5个人多大?

程序分析:

利用递归的方法,递归分为回推和递推两个阶段。要想知道第5个人岁数,需知道第4人的岁数,依次类推,推到第1人(10岁),再往回推。

#include

/*

* 请使用递归函数完成本题

* 小编已将正确代码放在左侧任务的“不知道怎么办”里

* 小编希望各位童鞋独立完成哦~

*/

//定义一个函数,传送人员序号进去,返回该序号员工的年龄。

int getAge(numPeople)

{

//定义返回的年龄

int age;

//如果是第1个人的时候,年龄为10岁

if(numPeople==1)

age=10; //这是回推墙,也就是结束递归的条件。

else

//还没接触到回推墙,就自我调用,谓之递归。

age = getAge(numPeople-1)+2; //年龄等于上一个人的年龄加2

return age;

}

int main()

{

printf("第5个人的年龄是%d岁", getAge(5));

return 0;

}

例题

猴子第一天摘下N个桃子,当时就吃了一半,还不过瘾,就又多吃了一个。第二天又将剩下的桃子吃掉一半,又多吃了一个。以后每天都吃前一天剩下的一半零一个。到第10天在想吃的时候就剩一个桃子了,问第一天共摘下来多少个桃子?并反向打印每天所剩桃子数。

#include

//定义一个函数,输入第n天,返回该天剩下的桃子数

int getPeachNumber(n)

{

int num; //定义所剩桃子数

if(n==10)

{

num=1; //递归结束条件,即回推墙

return num;

}

else

{

num = (getPeachNumber(n+1) + 1) * 2; //递推关系

printf("第%d天所剩桃子%d个\n", n, num); //天数,所剩桃子个数

}

return num;

}

int main()

{

int num = getPeachNumber(1);

printf("猴子第一天摘了:%d个桃子。\n", num);

}

递归(recursion):程序调用自身的编程技巧。递归满足2个条件:

1)有反复执行的过程(调用自身)

2)有跳出反复执行过程的条件(递归出口)

递归例子:

(1)阶乘

n! = n * (n-1) * (n-2) * ...* 1(n>0)

//阶乘

int recursive(int i)

{

int sum = 0;

if (0 == i)

return (1);

else

sum = i * recursive(i-1);

return sum;

}

(2)河内塔问题

//河内塔

void hanoi(int n,int p1,int p2,int p3)

{

if(1==n)

cout<<"盘子从"<

else

{

hanoi(n-1,p1,p3,p2);

cout<<"盘子从"<

hanoi(n-1,p2,p1,p3);

}

}

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

如1,2,3三个元素的全排列为:

1,2,3

1,3,2

2,1,3

2,3,1

3,1,2

3,2,1

//全排列

inline void Swap(int &a,int &b)

{

int temp=a;

a=b;

b=temp;

}

void Perm(int list[],int k,int m)

{

if (k == m-1)

{

for(int i=0;i

{

printf("%d",list[i]);

}

printf("n");

}

else

{

for(int i=k;i

{

Swap(list[k],list[i]);

Perm(list,k+1,m);

Swap(list[k],list[i]);

}

}

}

(4)斐波那契数列

斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……这个数列从第三项开始,每一项都等于前两项之和。

有趣的兔子问题:

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?

分析如下:

第一个月小兔子没有繁殖能力,所以还是一对;

两个月后,生下一对小兔子,总数共有两对;

三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,总数共是三对;

……

依次类推可以列出下表:

//斐波那契

long Fib(int n)

{

if (n == 0)

return 0;

if (n == 1)

return 1;

if (n > 1)

return Fib(n-1) + Fib(n-2);

}

(4)判定一系列字符串中是否有相同的内容

public class T {

public static void main(String[] args) {

String[] a = {"a1","a2","a3","b3","c","b","33","33"};

boolean b = new T().fun(0, a);

System.out.println(b);

}

public boolean fun(int n,String[] a){

boolean b = false;

if(n == a.length){

b = true;

}else{

for(int i = n; i < a.length-1; i++){

System.out.println(n+" "+(i+1));

if(a[n].equals(a[i+1])){

return false;

}

}

n++;

fun(n,a);

}

return b;

}

}

1.Fibonacci数

我们直到Fibonacci数的递推公式为:F(0)=F(1)=1,F(n)=F(n-1)+F(n-2) n>=2;

这个明显地给出了递归边界n=0或1的时候F(n)的值,和递归逻辑F(n)=F(n-1)+F(n-2),即递推公式.所以这个递归函数不难书写

int F(int n)//函数返回一个数对应的Fibonacci数

2.阶乘

阶乘的递归公式为:

3.数组求和

给一个数组a[]:a[0],a[1],...,a[n-1]如何用递归的方式求和?

仍然是两个问题:递归边界和递归公式.

递归边界是什么?一时不容易想到,但是我们想到了求和,多个数的求和过程是什么,x,y,z,w 手动求和的过程是什么?步骤如下:

x+y=a,任务变为a,z,w求和

a+z=b,任务变为b,w求和

b+w=c得出答案

思考一下,【得出答案】这一步为什么就可以得出答案呢?(废话?)是因为,一个数不用相加就能得出答案.

所以,递归的边界就是只有一个数.

所以,递归边界有了,那么递归公式呢?其实手动计算过程中,隐含了递归公式:

其中+为求两个数的和,F为求多个数的和的递归函数.代码如下:#include

using namespace std;

int F(int a[],int start,int end)

{

if(start==end)//递归边界

return a[start];

return a[start] + F(a,start+1,end);//递归公式

}

int main()

{

int a[] = {1,2,3,4,5};

int s=0,e=4;

cout << F(a,s,e) << endl;

return 0;

}

4.求数组元素最大值

手动求最大值的过程是什么,遍历+比较,过程如下:

例如,求3,2,6,7,2,4的最大值:先设置最大值max=-999999,然后将max和数组元素逐个(遍历)比较如果a[i]>max,则更新max的值为a[i],否则max不变,继续向后遍历,直到遍历结束.

max<3,则max=3

max>2,max=3不变

max<6,则max=6

max<7,则max=7

max>2,max=7不变

max>4,max=7不变

遍历结束,max=7为最大值.

和求和类似,递归的公式如下:

其中max为求两个数的较大值函数,F为求多个数的最大值的递归函数.代码如下:

#include

using namespace std;

#define max(a,b) (a>b?a:b)

int F(int a[],int s,int e)

{

if(s==e)

return a[s];

else if(s+1 == e)//递归边界

return max(a[s],a[e]);

return max(a[s],F(a,s+1,e));//递归公式!!!

}

int main()

{

int a[] = {5,1,4,6,2};

int s = 0,e = 4;

cout << F(a,s,e) << endl;

return 0;

}

之所以,说上面的几个例子是【简单例子】,是因为上述所有的递归都属于【单向递归】.单向递归,递归的路径就是一个方向,所以思路相对比较容易想到.

-

线性递归数列

线性递归数列 【基础知识】 1、概念:①、递归式:一个数列}{n a 中的第n 项n a 与它前面若干项1-n a ,2-n a ,…,k n a -(n k <)的关系式称为递归式。 ②、递归数列:由递归式和初始值确定的数列成为递归数列。 2、常用方法:累加法,迭代法,代换法,代入法等。 3、思想策略:构造新数列的思想。 4、常见类型: 类型Ⅰ:???=≠+=+为常数)a a a n p n q a n p a n n ()0)(() ()(11(一阶递归) 其特例为:(1))0(1≠+=+p q pa a n n (2))0() (1≠+=+p n q pa a n n (3))0()(1≠+=+p q a n p a n n 解题方法:利用待定系数法构造类似于“等比数列”的新数列。 类型Ⅱ:???==≠≠+=++为常数) b a b a a a q p qa pa a n n n ,(,)0,0(2112(二阶递归) 解题方法:利用特征方程q px x +=2,求其根α、β,构造n n n B A a βα +=,代入初始值求得B A ,。 类型Ⅲ:)(1n n a f a =+其中函数)(x f 为基本初等函数复合而成。 解题方法:一般情况下,通过构造新数列可转化为前两种类型。 【例题】 例1、已知数列}{n a 满足以下递归关系?? ?=+=+14311a a a n n ,求通项n a 。 例2、已知数列}{n a 满足?? ?=-+=+2)12(211a n a a n n ,求通项n a 。 例3、已知数列}{n a 满足?? ?=≥+=+1)2(211a n na a n n ,求通项n a 。 例4、已知数列}{n a 满足?? ?==-=++2,1232112a a a a a n n n ,求通项n a 。 例5、由自然数组成的数列}{n a ,满足11=a ,mn a a a n m n m ++=+,求n a 。

递归算法与递归程序#

一、教学目标 1、知识与技能 (1).认识递归现象。 (2).使用递归算法解决问题往往能使算法的描述乘法而易于表达 (3).理解递归三要素:每次递归调用都要缩小规模;前次递归调用为后次作准备:递归调用必须有条件进行。 (4).认识递归算法往往不是高效的算法。 (5).了解递归现象的规律。 (6).能够设计递归程序解决适用于递归解决的问题。 (7).能够根据算法写出递归程序。 (8).了解生活中的递归现象,领悟递归现象的既有重复,又有变化的 特点,并 且从中学习解决问题的一种方法。 2、方法与过程 本节让同学们玩汉诺塔的游戏,导入递归问题,从用普通程序解决斐波那契的兔子问题入手,引导学生用自定义了一个以递归方式解决的函数过程解决问题,同时让同学们做三个递归练习,巩固提高。然后让学生做练习(2)和练习(3)这两道题目的形式相差很远,但方法和答案却是完全相同的练习,体会其中的奥妙,加深对递归算法的了解。最后用子过程解决汉诺塔的经典问题。 3、情感态度和价值观 结合高中生想象具有较强的随意性、更富于现实性的身心发展特点,综合反映出递归算法的特点,以及递归算法解答某些实践问题通常得很简洁,从而激发学生对程序设计的追求和向往。 二、重点难点 1、教学重点 (1)了解递归现象和递归算法的特点。

(2)能够根据问题设计出恰当的递归程序。 2、教学难点 (1)递归过程思路的建立。 (2)判断问题是否适于递归解法。 (3)正确写出递归程序。 三、教学环境 1、教材处理 教材选自《广东省普通高中信息技术选修一:算法与程序设计》第四章第五节,原教材的编排是以本节以斐波那契的兔子问题引人,导出递归算法,从而自定义了一个以递归方式解决的函数过程。然后利用子过程解决汉诺塔的经典问题。 教材经处理后,让同学们玩汉诺塔的游戏,导入递归问题,从用普通程序解决斐波那契的兔子问题入手,引导学生用自定义了一个以递归方式解决的函数过程解决问题,同时让同学们做三个递归练习,巩固提高。然后让学生做练习(2)和练习(3)这两道题目的形式相差很远,但方法和答案却都是完全相同的练习,体会其中的奥妙,加深对递归算法的了解。最后用子过程解决汉诺塔的经典问题。 教学方法采用讲解、探究、任务驱动和学生自主学习相结合 2、预备知识 学生已掌握了用计算机解决问题的过程,掌握了程序设计基础,掌握了解析法、穷举法、查找法、排序法设计程序的技巧。 3、硬件要求 建议本节课在多媒体电脑教室中完成,最好有广播教学系统或投影仪,为拓展学习,学生机应允许上互联网。 4、所需软件 学生机要安装VB6.0或以上版本。 5、所需课时 2课时(90分钟)

《递归算法与递归程序》教学设计

递归算法与递归程序 岳西中学:崔世义一、教学目标 1知识与技能 (1) ?认识递归现象。 (2) ?使用递归算法解决冋题往往能使算法的描述乘法而易于表达 (3) ?理解递归三要素:每次递归调用都要缩小规模;前次递归调用为后次作准备:递归调用必须有条件进行。 (4) ?认识递归算法往往不是咼效的算法。 (5) ? 了解递归现象的规律。 (6) ?能够设计递归程序解决适用于递归解决的问题。 (7) ?能够根据算法写出递归程序。 (8) ? 了解生活中的递归现象,领悟递归现象的既有重复,又有变化的特点,并且从中学习解决问题的一种方法。 2、方法与过程 本节让同学们玩汉诺塔的游戏,导入递归问题,从用普通程序解决斐波那契的兔子问题入手,引导学生用自定义了一个以递归方式解决的函数过程解决问题,同时让同学们做三个递归练习,巩固提高。然后让学生做练习(2) 和练习(3)这两道题目的形式相差很远,但方法和答案却是完全相同的练习,体会其中的奥妙,加深对递归算法的了解。最后用子过程解决汉诺塔的经典问题。 3、情感态度和价值观 结合高中生想象具有较强的随意性、更富于现实性的身心发展特点,综合反映出递归算法的特点,以及递归算法解答某些实践问题通常得很简洁,从而激发学生对程序设计的追求和向往。 二、重点难点 1、教学重点 (1) 了解递归现象和递归算法的特点。 (2) 能够根据问题设计出恰当的递归程序。 2、教学难点 (1) 递归过程思路的建立。 (2) 判断冋题是否适于递归解法。 (3) 正确写出递归程序。 三、教学环境 1、教材处理 教材选自《浙江省普通高中信息技术选修:算法与程序设计》第五章,原教材的编排是以本节以斐波那契的兔子问题引人,导出递归算法,从而自 定义了一个以递归方式解决的函数过程。然后利用子过程解决汉诺塔的经典问题。 教材经处理后,让同学们玩汉诺塔的游戏,导入递归问题,从用普通程序解决斐波那契的兔子问题入手,引导学生用自定义了一个以递归方式解决的函数过程解决问题,同时让同学们做三个递归练习,巩固提高。然后让学生做练习⑵ 和练习

图习题及标准答案

图习题及标准答案

————————————————————————————————作者:————————————————————————————————日期:

第7章图 一、选择题 1.对于一个具有n个顶点和e条边的有向图,在用邻接表表示图时,拓扑排序算法时间复杂度为() A) O(n) B) O(n+e) C) O(n*n) D) O(n*n*n) 【答案】B 2.设无向图的顶点个数为n,则该图最多有()条边。 A)n-1 B)n(n-1)/2 C) n(n+1)/2 D)n2 【答案】B 3.连通分量指的是() A)无向图中的极小连通子图 B)无向图中的极大连通子图 C)有向图中的极小连通子图 D)有向图中的极大连通子图 【答案】B 4.n个结点的完全有向图含有边的数目() A)n*n B)n(n+1)C)n/2 D)n*(n-1) 【答案】D 5.关键路径是() A) AOE网中从源点到汇点的最长路径 B) AOE网中从源点到汇点的最短路径 C) AOV网中从源点到汇点的最长路径 D) AOV网中从源点到汇点的最短路径 【答案】A 6.有向图中一个顶点的度是该顶点的() A)入度 B)出度 C)入度与出度之和 D)(入度+出度)/2 【答案】C 7.有e条边的无向图,若用邻接表存储,表中有()边结点。 A) e B) 2e C) e-1 D) 2(e-1)

【答案】B 8.实现图的广度优先搜索算法需使用的辅助数据结构为() A)栈 B)队列 C)二叉树 D)树 【答案】B 9.实现图的非递归深度优先搜索算法需使用的辅助数据结构为() A)栈 B)队列 C)二叉树 D)树 【答案】A 10.存储无向图的邻接矩阵一定是一个() A)上三角矩阵 B)稀疏矩阵 C)对称矩阵 D)对角矩阵【答案】C 11.在一个有向图中所有顶点的入度之和等于出度之和的()倍 A) 1/2 B)1 C) 2 D) 4 【答案】B 12.在图采用邻接表存储时,求最小生成树的 Prim 算法的时间复杂度为()A) O(n) B) O(n+e) C) O(n2) D) O(n3) 【答案】B 13.下列关于AOE网的叙述中,不正确的是() A)关键活动不按期完成就会影响整个工程的完成时间 B)任何一个关键活动提前完成,那么整个工程将会提前完成 C)所有的关键活动提前完成,那么整个工程将会提前完成 D)某些关键活动提前完成,那么整个工程将会提前完成 【答案】B 14.具有10个顶点的无向图至少有多少条边才能保证连通() A) 9 B)10 C) 11 D) 12 【答案】A 15.在含n个顶点和e条边的无向图的邻接矩阵中,零元素的个数为()A) e B)2e C) n2-e D)n2-2e 【答案】D 16.对于一个具有n个顶点和e条边的无向图,如果采用邻接表来表示,则其表

高中信息技术 算法与程序设计-递归算法的实现教案 教科版

递归算法的实现 【基本信息】 【课标要求】 (三)算法与问题解决例举 1. 内容标准 递归法与问题解决 (1)了解使用递归法设计算法的基本过程。 (2)能够根据具体问题的要求,使用递归法设计算法、编写递归函数、编写程序、求解问题。 【教材分析】 “算法的程序实现”是《算法与程序设计》选修模块第三单元的内容,本节课是“递归算法的程序实现”,前面学习了用解析法解决问题、穷举法解决问题、在数组中查找数据、对数进行排序以及本节的前一小节知识点“什么是自定义函数”的学习,在学习自定义函数的基础上,学习递归算法的程序实现是自定义函数的具体应用,培养学生“自顶向下”、“逐步求精”的意识起着重要的作用。 『递归算法在算法的学习过程中是一个难点,在PASCAL和C语言等程序语言的学习过程中,往往是将其放在“函数与过程”这一章节中来讲解的。递归算法的实现也是用函数或是过程的自我调用来实现的。从这一点上来讲,作者对教材的分析与把握是准确的,思路是清晰的,目标是明确的。』 【学情分析】 教学对象是高中二年级学生,前面学习了程序设计的各种结构,在学习程序设计各种结构的应用过程中培养了用计算机编程解决现实中问题的能力,特别是在学习循环语句的过程中,应用了大量的“递推”算法。前一节课学习了如何自定义函数,在此基础上学习深入学习和体会自定义函数的应用。以递推算法的逆向思维进行求解问题,在学习过程中体会递归算法的思想过程。多维度的思考问题和解决问题是提高学生的学习兴趣关键。 『递归算法的本质是递推,而递推的实现正是通过循环语句来完成的。作者准确把握了学生前面的学习情况,对递归算法的本质与特征也分析的很透彻,可以说作者对教学任务的分析是很成功的,接来就要看,在成功分析的基础上作者是如何通过设计教学来解决教学难点的了。』 【教学目标】

数据结构复习要点

第一章数据结构基本概念 1、基本概念:理解什么是数据、数据对象、数据元素、数据结构、数据的逻辑结构与物理结构、逻辑结构与物理结构间的关系。 2、面向对象概念:理解什么是数据类型、抽象数据类型、数据抽象和信息隐蔽原则。了解什么是面向对象。由于目前关于这个问题有许多说法,我们采用了一种最流行的说法,即Coad与Yourdon 给出的定义:面向对象= 对象+ 类+ 继承+ 通信。 要点: ·抽象数据类型的封装性 ·面向对象系统结构的稳定性 ·面向对象方法着眼点在于应用问题所涉及的对象 3、数据结构的抽象层次:理解用对象类表示的各种数据结构 4、算法与算法分析:理解算法的定义、算法的特性、算法的时间代价、算法的空间代价。 要点:·算法与程序的不同之处需要从算法的特性来解释 ·算法的正确性是最主要的要求 ·算法的可读性是必须考虑的 ·程序的程序步数的计算与算法的事前估计 ·程序的时间代价是指算法的渐进时间复杂性度量 第二章数组 1、作为抽象数据类型的数组:数组的定义、数组的按行顺序存储与按列顺序存储 要点: ·数组元素的存放地址计算 2、顺序表:顺序表的定义、搜索、插入与删除 要点: ·顺序表搜索算法、平均比较次数的计算 ·插入与删除算法、平均移动次数的计算 3、多项式:多项式的定义 4、字符串:字符串的定义及其操作的实现 要点: ·串重载操作的定义与实现

第三章链接表 1、单链表:单链表定义、相应操作的实现、单链表的游标类。 要点: ·单链表的两种定义方式(复合方式与嵌套方式) ·单链表的搜索算法与插入、删除算法 ·单链表的递归与迭代算法 2、循环链表:单链表与循环链表的异同 3、双向链表:双向链表的搜索、插入与删除算法、链表带表头结点的优点 4、多项式的链接表示 第四章栈与队列 1、栈:栈的特性、栈的基本运算 要点: ·栈的数组实现、栈的链表实现 ·栈满及栈空条件、抽象数据类型中的先决条件与后置条件 2、栈的应用:用后缀表示计算表达式,中缀表示改后缀表示 3、队列:队列的特性、队列的基本运算 要点: ·队列的数组实现:循环队列中队头与队尾指针的表示,队满及队空条件·队列的链表实现:链式队列中的队头与队尾指针的表示、 4、双向队列:双向队列的插入与删除算法 5、优先级队列:优先级队列的插入与删除算法 第五章递归与广义表 1、递归:递归的定义、递归的数据结构、递归问题用递归过程求解 要点:·链表是递归的数据结构,可用递归过程求解有关链表的问题 2、递归实现时栈的应用 要点:·递归的分层(树形)表示:递归树

递归算法和非递归算法的区别和转换

递归算法向非递归算法转换 递归算法实际上是一种分而治之的方法,它把复杂问题分解为简单问题来求解。对于某些复杂问题(例如hanio塔问题),递归算法是一种自然且合乎逻辑的解决问题的方式,但是递归算法的执行效率通常比较差。因此,在求解某些问题时,常采用递归算法来分析问题,用非递归算法来求解问题;另外,有些程序设计语言不支持递归,这就需要把递归算法转换为非递归算法。 将递归算法转换为非递归算法有两种方法,一种是直接求值,不需要回溯;另一种是不能直接求值,需要回溯。前者使用一些变量保存中间结果,称为直接转换法;后者使用栈保存中间结果,称为间接转换法,下面分别讨论这两种方法。 1. 直接转换法 直接转换法通常用来消除尾递归和单向递归,将递归结构用循环结构来替代。 尾递归是指在递归算法中,递归调用语句只有一个,而且是处在算法的最后。例如求阶乘的递归算法: long fact(int n) { if (n==0) return 1; else return n*fact(n-1); } 当递归调用返回时,是返回到上一层递归调用的下一条语句,而这个返回位置正好是算法的结束处,所以,不必利用栈来保存返回信息。对于尾递归形式的递归算法,可以利用循环结构来替代。例如求阶乘的递归算法可以写成如下循环结构的非递归算法: long fact(int n) { int s=0; for (int i=1; i<=n;i++) s=s*i; //用s保存中间结果 return s; } 单向递归是指递归算法中虽然有多处递归调用语句,但各递归调用语句的参数之间没有关系,并且这些递归调用语句都处在递归算法的最后。显然,尾递归是单向递归的特例。例如求斐波那契数列的递归算法如下: int f(int n) {

c语言迷宫问题的求解(栈和递归)

实验报告 【实验名称】项目一迷宫问题的求解 【实验目的】 1.了解栈的基本操作以及充分理解栈的特点。熟悉掌握栈的基本操作和结构体 的运用。 2.学会用栈或者递归方法解决迷宫问题。 【实验原理】 1.本次实验中,以二维数组maze[row][col]表示迷宫,0表示通路,1表示墙,在构建迷宫时,为了清晰显示,在最外层添加一圈墙。 2.算法的核心思想是利用栈后进先出的特点,对迷宫进行探索,如果此路可行,则将此坐标的信息入栈,如果此路不通,则将此坐标的信息出栈。 3.输入形式:根据控制台的提示,依次输入迷宫的行数、列数,然后输入迷宫,再输入入口和出口坐标。 4.输出形式:由用户选择,由递归、非递归两种求解方式输出一条迷宫通路。以非递归方式会显示一种求解方案,并给出相应的三元组序列和迷宫方阵;以递归方式则会显示出所有的路线。 【实验内容】 1.需求分析 (1)问题描述 以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 要求以递归和非递归两种方式分别输出一条迷宫的通路,以带方向坐标和迷宫图像表示。

(2)基本要求 (1)首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出。其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如,对于下列数据的迷宫,输出一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),…。 (2)编写递归形式的算法,求得迷宫中所有可能的通路。 (3)以方阵形式输出迷宫及其通路。 2.概要设计 (1)栈的抽象数据类型 ADT Stack{ 数据对象:D={ai|ai∈ElemSet, i=1,2, …,n, n≥0} 数据关系:R1={|ai-1,ai∈D, i=1,2, …,n } 约定an端为栈顶,a1端为栈底。 基本操作: InitStack( &S ) 操作结果:构造一个空栈S。 DestroyStack ( &S ) 初始条件:栈S已存在。 操作结果:销毁栈S。 ClearStack( &S ) 初始条件:栈S已存在。 操作结果:将S清为空栈。 StackEmpty( S ) 初始条件:栈S已存在。 操作结果:若S为空栈,则返回TRUE,否则返回FALSE。 StackLength( S ) 初始条件:栈S已存在。 操作结果:返回S的数据元素个数,即栈的长度。 GetTop( S, &e ) 初始条件:栈S已存在且非空。 操作结果:用e返回S的栈顶元素。 Push( &S, e ) 初始条件:栈S已存在。 操作结果:插入元素e为新的栈顶元素。 Pop( &S, &e ) 初始条件:栈S已存在且非空。 操作结果:删除S的栈顶元素,并用e返回其值。 }ADT Stack (2)程序模块

以邻接矩阵方式确定有向网课程设计报告

以邻接矩阵方式确定有向网课程设计报告

《数据结构》 课程设计报告 设计题目:以邻接矩阵方式确定有向网班级: 姓名: 学号: 完成日期:

一、需求分析 1、运行环境(软、硬件环境): 处理器:英特尔酷睿(Core) i5-2410M CPU 2.30GHz 物理内存:2G 操作系统:Microsoft Windowns 7 开发环境:Microsoft Visual Studio 2008 2、程序所实现的功能: (1)建立并显示出它的邻接链表; (2)以非递归的方式进行深度优先遍历,显示遍历的结果, (并随时显示栈的入、出情况); (3)对改图进行拓扑排序,显示拓扑排序的结果,并随时 显示入度域的变化情况; (4)给出某一确定顶点到所有其他顶点的最短路径; 3、程序的输入,包含输入的数据格式和说明: (1)输入节点数个数 (2)输入顶点信息(空格隔开) (3)输入权值信息(以弧尾值弧头值权值信息,空格 隔开 0 0 0结束;)文档由风行播放器https://www.360docs.net/doc/f59272227.html,/暴风影音 2014: https://www.360docs.net/doc/f59272227.html,/整理 4、程序的输出,程序输出的形式: (1)邻接链表输出(2)深度优先遍历输出(3)拓扑排序输出(4)最短路径输出 5、测试数据: (1)节点个数:5个 (2)顶点信息:a b c d e (3)权值信息:a b 1 b c 2 c d 3 d e 4 a d 5 d c 6 0 0 0 二、设计说明

1、算法设计的思想: 建程序主要是通过建立一个图的模板类来调用相应的构造函数以及相应的成员函数来实现其功能,首先用结构体来存储边节点和顶点节点,用邻接矩阵来存储此有向图,遍历的过程采用双从循环来使得遍历达到最底端,最短路径采用了递归的思想循环调用最短路径函数来完成最短路径的查找,拓扑排序中首先优先输出入度为零的节点,然后通过删除该节点继续此过程进行排序。 2、主要的数据结构设计说明: 图的邻接矩阵结构设计:顶点数、弧数、矩阵数组、和点数组 栈结构:包括栈顶和栈底 点结构:包括顶点和弧相关的指针信息。 3、程序的主要流程图: 有向图 输出邻接表深 度 优 先 遍 拓 扑 排 序 入 度 域 变 化 最 短 路 径历 4、主要模块和函数: 1、邻接矩阵创建有向网void CreatGraph(MGraph *g) 伪码:依次存储节点数、顶点信息、权值 2、打印有向网的邻接矩阵void PrintGraph(MGraph *g) 伪码:依次打印邻接矩阵 3、打印有向网的邻接表void PrintList(MGraph *g)

算法设计及分析递归算法典型例题

算法递归典型例题 实验一:递归策略运用练习 三、实验项目 1.运用递归策略设计算法实现下述题目的求解过程。 题目列表如下: (1)运动会开了N天,一共发出金牌M枚。第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。到了第N天刚好还有金牌N枚,到此金牌全部发完。编程求N和M。 (2)国王分财产。某国王临终前给儿子们分财产。他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i 个儿子i份,再加上剩余财产的1/10。每个儿子都窃窃自喜。以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。请用程序回答,老国王共有几个儿子?财产共分成了多少份? 源程序: (3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。问这鱼缸里原有多少条金鱼? (4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少? (5)猴子吃桃。有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子? (6)小华读书。第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页? (7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子? 四、实验过程 (一)题目一:…… 1.题目分析 由已知可得,运动会最后一天剩余的金牌数gold等于运动会举行的天数由此可倒推每一 天的金牌剩余数,且每天的金牌数应为6的倍数。 2.算法构造 设运动会举行了N天, If(i==N)Gold[i]=N; Else gold[i]=gold[i+1]*7/6+i;

递归方程解法

递推关系解法补充 (取自[美]C.L.Liu 著,刘振宏译《离散数学基础》,?邮电出版社,1982.2,??P258) 一、有关定义及术语 1. 递推关系或差分方程:对于序列a 0,a 1,...,a n ,...,一个关系到a n 与几个a i (i

Astar算法与深度优先算法解决走迷宫问题

#include "stdafx.h" #include #include #include using namespace std; int direc[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; enum Flag { SEAL, OPEN, UNVISITED }; typedef char byte; typedef struct st{ int i,j; byte di; }st; st stk[500]; int top = -1; typedef struct node { int _x,_y; int _G; int _H; int _F; struct node *pre; }Queue_Node; typedef struct { Flag flag; Queue_Node *point; }Seal; int _maze[10][10] = { {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1}, {1,0,1,0,0,0,1,0,0,1}, {1,0,1,1,1,0,1,1,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} };

class A_Star { public:A_Star() { input(); } ~A_Star() { for(int i=1;i<=_len;++i) { for(int j=1;j<=_wid;++j) { if(_seal[i][j].point!=NULL) { delete _seal[i][j].point; } } } for(int i=0;i<=_len;++i) { delete []_seal[i]; delete []_maze[i]; } delete []_seal; delete []_maze; } //迷宫输入函数 void input() { //_len:长_wid:宽//起点坐标(_sx,_sy),目标点坐标(_ex,_ey) _len=10; _wid=10; _seal=new Seal*[_len+1]; _maze=new unsigned char*[_len+1]; for(int i=0;i<=_len;++i) { _seal[i]=new Seal[_wid+1]; _maze[i]=new unsigned char[_wid+1]; } for(int i=1;i<=_len;++i) { for(int j=1;j<=_wid;++j) { _seal[i][j].flag=UNVISITED; _seal[i][j].point=NULL; } } _sx=2; _sy=2; _ex=9; _ey=9;

递归模式

递归模式 所谓递归,笼统地说,是指运用收集到的知识作为行动的基础去获得更多的知识。由于这里所涉及往往是多个甚至是无穷多个未知量,因此,所谓的递归事实上也就是指知识的“不断扩张”:“在解题的每一个阶段,我们都把关于一个新的分量的知识加到已经得到的知识上去,在每一阶段,我们又都要用已经得到的知识去得出更多的知识。我们要靠逐省逐省的占领去最后征服一个王国。在每一个阶段,我们利用已被征服了的省份作为行动基地去征服下一个省份。” 例 关于前n 个自然数的k 次幂的和k k k k k n S ++++= 321的计算,可以看成应用递归模式去解决问题的一个典型例子。 由于k 是任何一个自然数,因此我们在此所要计算的就是无穷多个未知量,它们排成了如下的序列:k S S S S ,,,,210 ???显然, S 0是十分容易求得的: n S =++++=11110 进而,在此此基础上可得到如下的递推关系,它把上述序列中的每一个项k S 与它前面的各个项121,,,S S S k k --和0S 联系起来: ∵ 1)1(12111211111++++++=++-+-++++m C m C m C m C m m k k k k k k k k k k ∴ 1)1(12111211111+++++=-++-+-++++m C m C m C m C m m k k k k k k k k k k 令n m ,,3,2,1 =,得 111111************+++++=-+-+-++++k k k k k k k k k k C C C C 122222312111211111+++++=-+-+-++++k k k k k k k k k k C C C C 133333412111211111+++++=-+-+-++++k k k k k k k k k k C C C C ………………………………。 1)1(12111211111+++++=-++-+-++++n C n C m C n C n n k k k k k k k k k k 将上面n 个式子相加得 (n+1)k+1-1=(k+1) S k +21+k C S k-1+31+k C S k-2+???+ S 0。 由此,如果我们已经知道了121,,,S S S k k --和0S ,由所说的关系式便可以把S k 确定出来;又由于我们已经求得了S 0,因此,我们就可按照指定的次序,“一个接一个依次地”递推地把所有的项都找出来。例如,在上述的递推公式中,如令k=1, 就有01221)1(S S n +=-+

递归算法详解

递 归 冯文科 一、递归的基本概念。 一个函数、概念或数学结构,如果在其定义或说明内部直接或间接地出现对其本身的引 用,或者是为了描述问题的某一状态,必须要用至它的上一状态,而描述上一状态,又必须用到它的上一状态……这种用自己来定义自己的方法,称之为递归或递归定义。在程序设计中,函数直接或间接调用自己,就被称为递归调用。 二、递归的最简单应用:通过各项关系及初值求数列的某一项。 在数学中,有这样一种数列,很难求出它的通项公式,但数列中各项间关系却很简单,于是人们想出另一种办法来描述这种数列:通过初值及n a 与前面临近几项之间的关系。 要使用这样的描述方式,至少要提供两个信息:一是最前面几项的数值,一是数列间各项的关系。 比如阶乘数列 1、2、6、24、120、720…… 如果用上面的方式来描述它,应该是: ???>==-1 ,1,11n na n a n n 如果需要写一个函数来求n a 的值,那么可以很容易地写成这样:

这就是递归函数的最简单形式,从中可以明显看出递归函数都有的一个特点:先处理一 些特殊情况——这也是递归函数的第一个出口,再处理递归关系——这形成递归函数的第二个出口。 递归函数的执行过程总是先通过递归关系不断地缩小问题的规模,直到简单到可以作为 特殊情况处理而得出直接的结果,再通过递归关系逐层返回到原来的数据规模,最终得出问题的解。 以上面求阶乘数列的函数)(n f 为例。如在求)3(f 时,由于3不是特殊值,因此需要计 算)2(*3f ,但)2(f 是对它自己的调用,于是再计算)2(f ,2也不是特殊值,需要计算 )1(*2f ,需要知道)1(f 的值,再计算)1(f ,1是特殊值,于是直接得出1)1(=f ,返回上 一步,得2)1(*2)2(==f f ,再返回上一步,得62*3)2(*3)3(===f f ,从而得最终解。 用图解来说明,就是 下面再看一个稍复杂点的例子。 【例1】数列}{n a 的前几项为

递归算法的优缺点

○1优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。 ○2缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。 边界条件与递归方程是递归函数的二个要素 应用分治法的两个前提是问题的可分性和解的可归并性 以比较为基础的排序算法的最坏倩况时间复杂性下界为0(n·log2n)。 回溯法以深度优先的方式搜索解空间树T,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T。 舍伍德算法设计的基本思想: 设A是一个确定性算法,当它的输入实例为x时所需的计算时间记为tA(x)。设Xn是算法A的输入规模为n的实例的全体,则当问题的输入规模为n时,算法A所需的平均时间为 这显然不能排除存在x∈Xn使得的可能性。希望获得一个随机化算法B,使得对问题的输入规模为n的每一个实例均有 拉斯维加斯( Las Vegas )算法的基本思想: 设p(x)是对输入x调用拉斯维加斯算法获得问题的一个解的概率。一个正确的拉斯维加斯算法应该对所有输入x均有p(x)>0。 设t(x)是算法obstinate找到具体实例x的一个解所需的平均时间 ,s(x)和e(x)分别是算法对于具体实例x求解成功或求解失败所需的平均时间,则有: 解此方程可得:

蒙特卡罗(Monte Carlo)算法的基本思想: 设p是一个实数,且1/2

采用非递归深度优先遍历算法

2007-05-27 晴 //采用非递归深度优先遍历算法,可以将回溯法表示为一个非递归过程 #include using namespace std; class Knap { friend int Knapsack(int p[],int w[],int c,int n ); //设置友元函数 public: void print() //定义类内函数打印结果 { for(int m=1;m<=n;m++) { cout<

}; private: int Bound(int i); void Backtrack(int i); int c; //背包容量 int n; //物品数 int *w; //物品重量数组int *p; //物品价值数组int cw; //当前重量 int cp; //当前价值 int bestp; //当前最优值int *bestx; //当前最优解int *x; //当前解 }; int Knap::Bound(int i) //装满背包

if(i<=n) b+=p/w*cleft; return b; } void Knap::Backtrack(int i) { if(i>n) { if(bestp

利用递归解决实际问题

数据结构上机实验报告题目:用递归方法解决问题 学生姓名 学生学号 学院名称计算机学院 专业计算机科学与技术 时间

目录 第一章需求分析 (1) 1.1 原题表述 (1) 1.2 问题解决方案 (1) 第二章概要设计 (2) 2.1 主要算法描述 (2) 2.2 主要算法分析 (2) 第三章详细设计 (3) 3.1 程序代码 (3) 第四章调试分析 (4) 4.1 出现的问题及解决方法 (4) 第五章测试分析 (5) 5.1 测试样例 (5)

第一章需求分析 1.1 原题表述 日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子?请设计递归算法解决该问题。 1.2 问题解决方案 由于最后每个人分得的橘子一样多,所以最后每个人手里的橘子有2520/6 = 420个。因为每个人在拿到上一个人给的以后又分了一部分给下一个(老大不同,老大是最后得到的。根据题目关系,可以算出老大开始有橘子240个。)根据每个人得到与给出橘子的关系,可以用递归算法解决问题。

2.1 主要算法描述 解决此问题主要使用递归运算。 由题目可以看出原来手中的加上得到的满足关系式: StartNum = 420 * (n -2)/(n - 1) 分给下一个人的橘子数: GiveNum = AfterGetNum / n; 下一个人的橘子数: nextStartNum = 420*(n-1)/(n-2) - GiveNum; 下一个人加上之前得到的橘子的总数: afterGetNum = nextStartNum + GiveNum; 以此使用递归算法可以算出各个孩子原来手中的橘子数。 2.2 主要算法分析 此递归算法的时间复杂度为O(n)

卷积递归深度学习在3D物体分类上的应用

卷积递归深度学习在3D物体分类中的应用 (Convolutional-Recursive Deep Learning for 3D Object Classification) Richard Socher, Brody Huval, Bharath Bhat, Christopher D. Manning, Andrew Y. Ng Computer Science Department, Stanford University, Stanford, CA 94305, USA 摘要 3D传感技术的最新进展使人们有可能轻松地拍摄彩色和深度信息并存的图片,以提高物体识别的图像。目前,大多数方法对于这个新的3D方式依赖于非常精心设计的特征。引入一个基于卷积和递归神经网络(CNN和RNN)组合的模型,用于特征学习和RGB-D图像分类。CNN层用于学习低水平的平移不变性的特征,然后作为多个固定树RNN的输入,以组成高阶特征。RNN可以被看作是结合卷积,并汇集到一个高效的、分层的操作。我们的主要结果是,甚至随机权重的RNN也组成强大的特征集。我们的模型在标准RGB-D对象集上获得了较好的艺术表现力,与其他可比的架构相比(如两层CNN),在训练和测试的阶段能更准确、快捷地得到结果。 1.简介 物体识别是计算机视觉中最困难的问题之一,并对于实用化家庭环境下的机器人十分重要。新的传感技术(如Kinect)可以记录高品质RGB和深度图象(RGB-D)信息,并且现在已经结合标准视觉系统在家用机器人中运用了。深度模式为复杂问题的总体目标检测提供有用的额外信息,由于深度信息是不随亮度或颜色的变化而变化的,并提供了几何线索使得可以更好地从背景中分离。目前,大多数基于RGB-D图像的物体识别使用手工设计的特征集,如二维图像的SIFT [2],三维点云的旋转图片[3],或特定的颜色,形状和几何特征[4,5]。 本文介绍了用于对象识别的第一卷积递归深度学习模型,该模型可以借鉴原始RGB-D图像。相比近期其他3D特征学习方法[6,7],我们的做法具有更快速度、不需要额外的输入渠道(如表面法线)、艺术性地检测家用物品的特点。图图1列出了我们的做法。训练和测试代码在https://www.360docs.net/doc/f59272227.html,上可以找到。 模型采用原始的RGB和深度图像进行分析,并首次分别从中提取特征。每一种模式首先输入一个卷积神经网络层(CNN,[8]),这个网络层提供了低层特征(如边缘)上有效的平移不变性,并且允许对象在一定程度上变形。汇集的滤波器相应随后传送给一个递归神经网络(RNN,[9]),它可以学习成分特征和部分交互作用。通过绑定权重和非线性的多个层次,将RNN分层地投入到低维空间中。 本文也探索了计算机视觉中新的深度学习架构。之前,RNN在自然语言处理

相关文档
最新文档