当前位置:首页 » 操作系统 » c递归算法经典实例

c递归算法经典实例

发布时间: 2022-11-05 05:15:05

㈠ 求用c语言实现二叉树层次遍历的递归算法,谢谢!!!

算法思想:层次遍历目前最普遍用的就是队列的那种方式,不是递归,但是用到while循环,既然题目要求用递归,可以用递归实现该while循环功能。算法如下:
void TransLevele(Tree *r)
{
if (r==NULL)
{
return ;
}
printf("%c",r->ch);
if (r->left != NULL)
{
InsertQueue(r->left);
}
if (r->right != NULL)
{
InsertQueue(r->right);
}

Tree *t = DeleteQueue();
TransLevele(t);
}
//测试程序,创建树输入例如ABD##E##C##,根左右创建的方式。
如下代码是测试通过的。
#include "stdlib.h"

#define MAX 100

typedef int Element;

typedef struct tree
{
Element ch;
struct tree *left;
struct tree *right;
}Tree;

typedef struct queue
{
Tree *a[MAX];
int front;
int rear;
}Queue;

Queue Qu;

void Init();
int InsertQueue(Element ch);
Tree *DeleteQueue();

void CreateTree(Tree **r);
void TransLevele(Tree *r);
void PrintTree(Tree *r);

int main()
{
Tree *r=NULL;
CreateTree(&r);
PrintTree(r);
printf("\n");
TransLevele(r);
return 0;
}

void Init()
{
int i=0;
for (i=0; i<MAX; i++)
{
Qu.a[i] = NULL;
}
Qu.front = 0;
Qu.rear = 0;
}
int InsertQueue(Tree *r)
{
if ( (Qu.rear+1)%MAX == Qu.front)
{
printf("Queue full!");
return 0;
}
Qu.a[Qu.rear] = r;
Qu.rear = (Qu.rear+1)%MAX;
return 1;
}
Tree *DeleteQueue()
{
if (Qu.front == Qu.rear)
{
printf("Queue empty");
return NULL;
}
Tree *t=NULL;
t = Qu.a[Qu.front];
Qu.front = (Qu.front+1)%MAX;
return t;
}

void CreateTree(Tree **r)
{
Element ch;
ch=getchar();
if (ch=='#')
{
(*r)=NULL;
return ;
}
*r = (Tree *)malloc(sizeof(Tree));
(*r)->ch = ch;
CreateTree(&((*r)->left));
CreateTree(&((*r)->right));
}
void PrintTree(Tree *r)
{
if (r==NULL)
{
return ;
}
printf("%c",r->ch);
PrintTree(r->left);
PrintTree(r->right);
}
void TransLevele(Tree *r)
{
if (r==NULL)
{
return ;
}
printf("%c",r->ch);
if (r->left != NULL)
{
InsertQueue(r->left);
}
if (r->right != NULL)
{
InsertQueue(r->right);
}

Tree *t = DeleteQueue();
TransLevele(t);
}

㈡ 关于c语言递归调用的经典例题,求跪大神详解 !

这是汉诺塔吧。
原理:(总共n个盘子)

1、将第一个位置(起始位置)上的n-1个盘子移到第二个位置上,此时第一个位置只剩第n个盘子
2、将第一个位置上的最后一个盘子(第n个盘子)移到第三个位置(目标位置)上,再将第二个位置上的n-1个盘子移到第三个位置上。
你不需要晓得n-1个盘子如何从一个位置移到另一个位置,让程序做。n-->n-1-->n-2......1,问题不断的小化,当n=1时,直接从第一个位置移到第三个位置,再倒过来推1-->2-->3......-->n。最终问题就会被解决。

hanoi()函数就是将问题小化,使n-->1
move()函数中char x是起始位置,char y是目标位置,即x-->y.用A、B、C来显示盘子是如何移动的

㈢ c语言算n的阶乘的递归算法

思路:递归求阶乘函数,如果输入的参数等于1则返回1,否则返回n乘以该函数下次递归。

参考代码:

#include<stdio.h>
intfun(intn)
{
if(n==1||n==0)return1;//如果参数是0或者1返回1
returnn*fun(n-1);//否则返回n和下次递归的积
}
intmain()
{
intn;
scanf("%d",&n);
printf("%d ",fun(n));
return0;
}
/*
5
120
*/

㈣ c语言递归函数

首先要理解递归的概念,先递后归
开始递
get(1) n=1不成立,执行else
get(2) n=2不成立,执行else
get(3) n=3不成立,执行else
get(4) n=4不成立,执行else
get(5) n=5不成立,执行else
get(6) n=6不成立, 执行else
get(7) n=7不成立, 执行else
get(8) n=8不成立, 执行else
get(9) n=9不成立 执行else
get(10) n=10成立,返回值1
开始归!
get(10) num=1
get(9) get(n+1)*2+2 = 1*2+2=4 //这里说下为什么不在递的时候计算else呢?因为在递的时候我们并不知道他们上一次的值,所以是没办法计算的,这里get(n+1)已经知道了上一次的值get(10)是1。
get(8) get(n+1)*2+2 = 4*2+2 =10
get(7) get(n+1)*2+2 = 10*2+2 = 22
get(6) get(n+1)*2+2 = 22*2+2 = 46
get(5) get(n+1)*2+2 = 46*2+2 = 94
get(4) get(n+1)*2+2 = 94*2+2 = 190
get(3) get(n+1)*2+2 = 190*2+2 = 382
get(2) get(n+1)*2+2 = 382*2+2 = 766
get(1) get(n+1)*2+2 = 766*2+2 = 1534
至此递归条件结束

㈤ c语言实现二叉树的先序,中序,后序的递归和非递归算法和层次遍历算法

#include<malloc.h> // malloc()等
#include<stdio.h> // 标准输入输出头文件,包括EOF(=^Z或F6),NULL等
#include<stdlib.h> // atoi(),exit()
#include<math.h> // 数学函数头文件,包括floor(),ceil(),abs()等

#define ClearBiTree DestroyBiTree // 清空二叉树和销毁二叉树的操作一样

typedef struct BiTNode
{
int data; // 结点的值
BiTNode *lchild,*rchild; // 左右孩子指针
}BiTNode,*BiTree;

int Nil=0; // 设整型以0为空
void visit(int e)
{ printf("%d ",e); // 以整型格式输出
}
void InitBiTree(BiTree &T)
{ // 操作结果:构造空二叉树T
T=NULL;
}

void CreateBiTree(BiTree &T)
{ // 算法6.4:按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义),
// 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。修改
int number;
scanf("%d",&number); // 输入结点的值
if(number==Nil) // 结点的值为空
T=NULL;
else // 结点的值不为空
{ T=(BiTree)malloc(sizeof(BiTNode)); // 生成根结点
if(!T)
exit(OVERFLOW);
T->data=number; // 将值赋给T所指结点
CreateBiTree(T->lchild); // 递归构造左子树
CreateBiTree(T->rchild); // 递归构造右子树
}
}

void DestroyBiTree(BiTree &T)
{ // 初始条件:二叉树T存在。操作结果:销毁二叉树T
if(T) // 非空树
{ DestroyBiTree(T->lchild); // 递归销毁左子树,如无左子树,则不执行任何操作
DestroyBiTree(T->rchild); // 递归销毁右子树,如无右子树,则不执行任何操作
free(T); // 释放根结点
T=NULL; // 空指针赋0
}
}

void PreOrderTraverse(BiTree T,void(*Visit)(int))
{ // 初始条件:二叉树T存在,Visit是对结点操作的应用函数。修改算法6.1
// 操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次
if(T) // T不空
{ Visit(T->data); // 先访问根结点
PreOrderTraverse(T->lchild,Visit); // 再先序遍历左子树
PreOrderTraverse(T->rchild,Visit); // 最后先序遍历右子树
}
}

void InOrderTraverse(BiTree T,void(*Visit)(int))
{ // 初始条件:二叉树T存在,Visit是对结点操作的应用函数
// 操作结果:中序递归遍历T,对每个结点调用函数Visit一次且仅一次
if(T)
{ InOrderTraverse(T->lchild,Visit); // 先中序遍历左子树
Visit(T->data); // 再访问根结点
InOrderTraverse(T->rchild,Visit); // 最后中序遍历右子树
}
}

void PostOrderTraverse(BiTree T,void(*Visit)(int))
{ // 初始条件:二叉树T存在,Visit是对结点操作的应用函数
// 操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次
if(T) // T不空
{ PostOrderTraverse(T->lchild,Visit); // 先后序遍历左子树
PostOrderTraverse(T->rchild,Visit); // 再后序遍历右子树
Visit(T->data); // 最后访问根结点
}
}

void main()
{
BiTree T;
InitBiTree(T); // 初始化二叉树T
printf("按先序次序输入二叉树中结点的值,输入0表示节点为空,输入范例:1 2 0 0 3 0 0\n");
CreateBiTree(T); // 建立二叉树T
printf("先序递归遍历二叉树:\n");
PreOrderTraverse(T,visit); // 先序递归遍历二叉树T
printf("\n中序递归遍历二叉树:\n");
InOrderTraverse(T,visit); // 中序递归遍历二叉树T
printf("\n后序递归遍历二叉树:\n");
PostOrderTraverse(T,visit); // 后序递归遍历二叉树T
}

㈥ c语言经典递归法算法的疑问:(必须用递归算法做出来哦) 题目请看问题补充

#include<stdio.h>

int jos(int n, int k); // n表示总共有多少人, k表示报数的第几个数退出

int main(void)
{
int n,k,s;
printf("请输入总人数和间隔数(中间以空格隔开)\n");
scanf("%d %d", &n, &k);
s = jos(n, k);
printf("获胜者是:%d\n", s);

return 0;
}

int jos(int n,int k)
{// 每次运行都返回当前淘汰出来的位置
int x;
if(n==1) // 当剩下最后一个的时候他就是获胜者
x=1;
else
{// 如果多余一个
x=(jos(n-1,k)+k)%n; // 继续从剩余的这些人中进行选取获胜(%n达到了循环的目的)(这里利用n-1时的淘汰位置加上k是下一个淘汰位置, 此时n又被减少)
if(x==0)
x=n;
}

return x;
}

/*
请输入总人数和间隔数(中间以空格隔开)
37 5
获胜者是:1
Press any key to continue
*/

㈦ C语言递归算法

本人学c++,c的语法已经淡忘了,但是递归不管什么语言都是一个原理
其实简单一点来说就像数学里面的数列的通项公式:
例如一个数列是2,4,6,8,10......
很容易就可以得到通项公式是a[n]=2*n n是大于0的整数
你肯定学过这个数列的另外一种表示方式就是: a[1]=2, a[n]=a[n-1]+2 n是大于1的整数
其实这就是一个递归的形式,只要你知道初始项的值,未知项和前几项之间的关系就可以知道整个数列。
程序例子:比如你要得到第x项的值
普通循环:
for(int i=1; i<=n; i++)
if (i == x)
cout << 2*i; /*cout 相当于 c里面的printf,就是输出.*/
递归:
int a(int x) {
if (x = 1)
return 2; /* 第一项那肯定是2了,这个也是递归的终止条件! */
else return a(x-1)+2; /* 函数自身调用自身是递归的一个特色 */
比如x=4,那么用数学表示就是a(4)=a(3)+2=(a(2)+2)+2=((a(1)+2)+2)+2
其实递归方法最接近自然,也是最好思考的一个方法,难点就是把对象建模成递归形式,但是好多问题本身就是以递归形式出现的。
普通递归就是数据结构上的堆栈,先进后出。
例如上面x=4,把a(4)放入栈底,然后放入a(3),然后a(2),a(1),a(1)的值已知,出栈,a(1)=2,a(2)出栈a(2)=a(1)+2=2+2=4,a(3)出栈a(3)=a(2)+2=(a(1)+2)+2=6,a(4)出栈a(4)=a(3)+2=(a(2)+2)+2=((a(1)+2)+2)+2=8
再比如楼上的阶乘例子,当n=0 或 1时,0!=1,1!=1,这个是阶乘的初始值,也是递归的终止条件。然后我们知道n!=n*(n-1)!,当n>1时,这样我们又有了递归形式,又可以以递归算法设计程序了。(楼上已给出谭老的程序,我就不写了)。
我给出一种优化的递归算法---尾递归。
从我给出的第一算法可以看出,先进栈再出栈,递归的效率是很低的。速度上完全比不上迭代(循环)。但是尾递归引入了一个新的函数参数,用这个新的函数参数来记录中间值.
普通递归阶乘fac(x),就1个x而已,尾递归用2个参数fac(x,y),y存放阶乘值。
所以谭老的程序就变成
// zysable's tail recursive algorithm of factorial.
int fac(int x, int y) {
if (x == 1)
return y;
else return fac(x-1, y*x);}
int ff(int x) {
if (x == 0)
return 1;
else return fac(x,1);}
对于这个程序我们先看函数ff,函数ff其实是对fac的一个封装函数,纯粹是为了输入方便设计的,通过调用ff(x)来调用fac(x,1),这里常数1就是当x=1的时候阶乘值了,我通过走一遍当x=3时的值即为3!来说明一下。
首先ff(3),x!=0,执行fac(3,1).第一次调用fac,x=3,y=1,x!=1,调用fac(x-1,y*x),新的x=2,y=3*1=3,这里可以看到,y已经累计了一次阶乘值了,然后x还是!=1,继续第三次调用fac(x-1,y*x),新的x=1,y=2*3=6,然后x=1了,返回y的值是6,也就是3!.你会发现这个递归更类似于迭代了。事实上我们用了y记录了普通递归时候,出栈的乘积,所以减少了出栈后的步骤,而且现在世界上很多程序员都在倡议用尾递归取消循环,因为有些在很多解释器上尾递归比迭代稍微效率一点.
基本所有普通递归的问题都可以用尾递归来解决。
一个问题以递归来解决重要的是你能抽象出问题的递归公式,只要递归公式有了,你就可以放心大胆的在程序中使用,另外一个重点就是递归的终止条件;
其实这个终止条件也是包含在递归公式里面的,就是初始值的定义。英文叫define initial value. 用普通递归的时候不要刻意让自己去人工追踪程序,查看运行过程,有些时候你会发现你越看越不明白,只要递归公式转化成程序语言正确了,结果必然是正确的。学递归的初学者总是想用追踪程序运行来让自己来了解递归,结果越弄越糊涂。
如果想很清楚的了解递归,有种计算机语言叫scheme,完全递归的语言,因为没有循环语句和赋值语句。但是国内人知道的很少,大部分知道是的lisp。
好了,就给你说到这里了,希望你能学好递归。

PS:递归不要滥用,否则程序极其无效率,要用也用尾递归。by 一名在美国的中国程序员zysable。

㈧ 求c语言的字符串逆序输出的递归算法

1.创建一个新的项目和。c文件,输入头和主要功能。

热点内容
电箱都有哪些配置 发布:2025-05-15 00:30:21 浏览:72
安卓qq邀请码在哪里寻找 发布:2025-05-15 00:02:04 浏览:33
三菱fx编程口 发布:2025-05-15 00:01:23 浏览:809
医院招商引资宣传片脚本 发布:2025-05-15 00:01:21 浏览:367
linuxcftp服务器 发布:2025-05-14 23:58:18 浏览:717
探岳什么配置才有驾驶模式选择 发布:2025-05-14 23:53:17 浏览:144
如何在手机上看无限流量密码 发布:2025-05-14 23:43:31 浏览:114
19投篮脚本 发布:2025-05-14 23:36:57 浏览:513
编译器怎么处理c变长数组 发布:2025-05-14 23:31:46 浏览:663
存折每天可以输错多少次密码 发布:2025-05-14 23:22:06 浏览:909