p354图的DFS(用栈消除递归调用)
来源:互联网 发布:mac dare you日常吗 编辑:程序博客网 时间:2024/05/24 02:57
首先看下面的递归代码,留意每层递归的栈需要保存什么变量
int dfsvisit(gve G,node *pnode,int *time){ edge *tmp=pnode->next; (*time)++; pnode->d=*time; pnode->color=gray; while (tmp!=NULL) { if (G.g[tmp->i].color==white) dfsvisit(G,&G.g[tmp->i],time); tmp=tmp->next; } pnode->color=black; (*time)++; pnode->f=*time; return 0;}
- 递归呢,就是一个函数不断调用自身,直到满足递归终止条件而返回。系统在一个递归调用过程中,首先是将当前递归层的局部变量保存在当前栈里面,再将下一层递归的变量入栈;当下一层递归退出的时候,从栈中读取恢复这些局部变量,准备根据新的情况再进行操作(有可能又是递归调用);如果当前递归层的操作都做完了,系统就会出栈,要返回值的也在这个时候返回
那么对照着上面的代码看:
- 首先看参数:
- gve G,递归过程中并没有变化,相当于全局变量
- node *pnode, 每层递归都不一样,需要保存在栈里面
- int *time,时间戳,对递归来说是全局变量
- 再看局部变量:
- edge *tmp,函数会对和点相连的边逐一探索,每探索一次tmp的值都会发生变化,因此需要用栈来保存
- 这样需要保存在栈里面的数据就确定了,pnode和tmp
- 接下来是如何控制递归过程,分析while循环
- 首先从栈里面恢复tmp,继续寻找下一条可用的边
- then语句:如果没有可用的边了,准备出栈,从栈中恢复pnode,修改该点的属性(实际上pnode只在出栈的时候用得上)
- else语句:如果有可用边,将tmp保存在栈里面,便于下次恢复,将下一层递归需要的参数入栈
下面这段代码可以完全替代上面的代码
typedef struct stack_element{ node *pnode; edge *tmp;}stack_element;typedef struct stack{ int size,tail; stack_element *head;}stack;int push(stack *visit_stack,node *pnode,edge *tmp){ if (visit_stack->tail==visit_stack->size-1) { printf("stack overflow!\n"); return 0; } visit_stack->tail++; visit_stack->head[visit_stack->tail].pnode=pnode; visit_stack->head[visit_stack->tail].tmp=tmp; return 0;}int pop(stack *visit_stack){ visit_stack->tail--; return 0;}int dfsvisit(gve G,node *pnode,int *time){ stack visit_stack; visit_stack.size=G.v; visit_stack.tail=-1; visit_stack.head=(stack_element *)malloc(sizeof(stack_element)*(G.v)); edge *tmp=pnode->next; (*time)++; pnode->d=*time; pnode->color=gray; push(&visit_stack,pnode,tmp); while (visit_stack.tail!=-1) { tmp=visit_stack.head[visit_stack.tail].tmp; while ((tmp!=NULL)&&(G.g[tmp->i].color!=white)) tmp=tmp->next; if (tmp==NULL) { pnode=visit_stack.head[visit_stack.tail].pnode; pnode->color=black; (*time)++; pnode->f=*time; pop(&visit_stack); } else { visit_stack.head[visit_stack.tail].tmp=tmp; push(&visit_stack,&G.g[tmp->i],G.g[tmp->i].next); (*time)++; visit_stack.head[visit_stack.tail].pnode->d=*time; visit_stack.head[visit_stack.tail].pnode->color=gray; } } free(visit_stack.head); return 0;}
0 0
- p354图的DFS(用栈消除递归调用)
- [数据结构]图的DFS用栈消除递归的C语言简单实现
- 关于尾递归调用消除
- hdu1997 汉诺塔VII(DFS递归调用)
- 尾递归结构的消除
- 消除文法的左递归
- 消除文法的左递归
- 【图的DFS】图的DFS非递归算法
- 图的DFS的非递归算法
- 图的邻接表的遍历(DFS(递归,非递归),BFS,拓扑排序)
- DFS非递归实现图的遍历
- DFS 的递归做法
- DFS的递归实现
- 图的深度优先搜索(DFS)简介与实现(递归与非递归方法)
- 图的深度优先和广度优先算法(DFS递归与非递归)
- 使用栈的递归与非递归DFS
- 水果消除(搜索之DFS)
- 非尾递归结构的消除
- 单片机程序优化
- iframe中单击关闭父页面中的菜单
- Redis在电商中如何设计使用
- Bower介绍
- JS 数组去重
- p354图的DFS(用栈消除递归调用)
- Picasso 源码分析
- 关于iOS开发中info.plist文件的解读
- 负载均衡实现,一个域名对应多个IP地址
- 给PLSQL插上飞翔的翅膀-PLSQL优化
- 企业究竟如何保存数据?从携程官网瘫痪事件说起
- R语言常用算法包
- AIX /var/adm/wtmp: Value too large to be stored in data type.
- 集合类的体系结构