作者:冯老师,华清远见嵌入式学院讲师。

一、递归的定义及特点

递归是指某个函数直接或间接的调用自身。问题的求解过程就是划分成许多相同性质的子问题的求解,而小问题的求解过程可以很容易的求出。递归问题的关键是如何将原问题划分成子问题。递归实现时必须要找到递归出口,即递归终止的条件。

递归程序结构清晰、思路明了。但是递归的执行过程却很让人费解,递归程序的调试也很不方便。由于递归调用是对函数自身的调用,在一次调用没有结束之前又开始了另外一次调用,按照作用域的规定,函数在执行终止之前是不能收回所占用的空间,必须保存下来,这也就意味着每一次的调用都要把分配的相应空间保存起来。为了更好管理这些空间,系统内部设置一个栈,用于存放每次函数调用与返回所需的各种数据,其中主要包括函数的调用结束的返回地址,返回值,参数和局部变量等。反复的进栈和出栈导致了递归程序效率很低。

二、递归转非递归的实现

简单递归一般就是根据递归式来找出递推公式,使用循环的方法来实现。

复杂递归一般就是模拟系统处理递归的机制,使用栈来保存回朔点来求解。下面通过树形结构遍历的非递归实现来举例说明。

三、树形结构的先序、中序、后序非递归实现

void preorder(bitree *r)
        {
                sqstack *s;
                bitree *p;

p = r;

if (r == NULL)
                return;

s = stack_create();
                if (s == NULL)
                return;

while (p || !stack_empty(s))
                {
                        while (p)
                        {
                                printf("%d ", p->data);
                                push(s, p);
                                p = p->left;
                        }
                        if (!stack_empty(s))
                        {
                                p = pop(s);
                                p = p->right;
                        }
                }
        }

void inorder(bitree *r)
        {
                sqstack *s;
                bitree *p;

p = r;

if (r == NULL)
                return;

s = stack_create();
                if (s == NULL)
                return;

while (p || !stack_empty(s))
                {
                        while (p)
                        {
                                push(s, p);
                                p = p->left;
                        }
                        if (!stack_empty(s))
                        {
                                p = pop(s);
                                printf("%d ", p->data);
                                p = p->right;
                        }
                }
        }

void postorder(bitree *r)
        {
                sqstack *s;
                bitree *pre = NULL, *cur;

if (r == NULL)
                return;

s = stack_create();
                if (s == NULL)
                return;

push(s, r);

while (!stack_empty(s))
                {
                        cur = top(s);

if ((cur->left == NULL && cur->right == NULL) ||
                        (pre != NULL && (pre == cur->left || pre == cur->right)))
                        {
                                printf("%d ", cur->data);
                                pop(s);
                                pre = cur;
                        }
                        else
                        {
                                if (cur->right != NULL)
                                push(s, cur->right);
                                if (cur->left != NULL)
                                push(s, cur->left);
                        }
                }
        }

文章来源:华清远见嵌入式学院;原文地址:http://www.embedu.org/Column/Column836.htm

更多相关嵌入式免费资料查看华清远见讲师博文》》

二叉树遍历的非递归实现相关推荐

  1. 漫谈二叉树遍历(非递归)

    ------这篇文章旨在提出一种简单方便,易于理解时空复杂度低且风格统一的二叉树非递归遍历方法. 从二叉树先序遍历开始 二叉树的先序遍历(非递归)相比中后序是最少花哨.最统一的.一般来说先序遍历的代码 ...

  2. java使用btree_java数据结构之二叉树遍历的非递归实现

    算法概述 递归算法简洁明了.可读性好,但与非递归算法相比要消耗更多的时间和存储空间.为提高效率,我们可采用一种非递归的二叉树遍历算法.非递归的实现要借助栈来实现,因为堆栈的先进后出的结构和递归很相似. ...

  3. 二叉树遍历(非递归)

    文章目录 二叉树遍历非递归版本 前序遍历 中序遍历 后序遍历 层序遍历 层序遍历+map记录高度 二叉树遍历非递归版本 前序遍历 如果右侧不为空,则右侧进栈,随后是左侧进栈.因为栈是先进后出,所以实现 ...

  4. 二叉树遍历(非递归遍历)

    #include <iostream> #include <vector> #include <stack>using namespace std;//思路分析 / ...

  5. 二叉树 2.0 -- 非递归遍历

    二叉树递归遍历存在的问题 如果我们的二叉树只有左子树,而且树的高度还很深的时候,这个时候递归调用遍历的时候,栈帧空间开辟的较大,很可能造成栈溢出.但是我们一个程序中,为堆分配的空间要比栈大的多,这个时 ...

  6. 信号放大器数据结构_[11/11]数据结构 二叉树应用(树型信号放大器,file transfer,遍历的非递归实现)...

    树型分布网络信号放大器 森林和二叉树的相互转换 并查集 例题:File transfer #include <iostream> using namespace std; //typede ...

  7. 对于二叉树三种非递归遍历方式的理解

    利用栈实现二叉树的先序,中序,后序遍历的非递归操作 栈是一种先进后出的数据结构,其本质应是记录作用,支撑回溯(即按原路线返回):因此,基于其的二叉树遍历操作深刻的体现了其特性: 若后续的输入和其前面的 ...

  8. 二叉树前序、中序和后序遍历的非递归实现

    1 二叉树的遍历 1.1 前序遍历 对于每棵子树,先处理根,然后处理左子树,最后处理右子树.根最先访问,所以是前序遍历. 1.2 中序遍历 对于每棵子树,先处理左子树,然后处理根,最后处理右子树.根中 ...

  9. 二叉树先中后序递归遍历与非递归遍历、层次遍历

    文章目录 1 先序遍历 1.1 先序遍历递归 1.2 先序遍历非递归 2 中序遍历 2.1 中序遍历递归 2.2 中序遍历非递归 3 后序遍历 3.1 后序遍历递归 3.2 后序遍历非递归 4 层序遍 ...

最新文章

  1. java中jtansforms,Java3D中的viewplatform的旋转
  2. python【蓝桥杯vip练习题库】ADV-147学霸的迷宫(广搜 bfs经典问题)
  3. 推荐:Visual Basic.NET Windows Forms 编程
  4. 将可执行程序的内存空间扩展到3GB(windows)
  5. 一个字稳,云原生产品家族支撑冬奥会九大业务场景,打造云上奥运新体验
  6. 第九章 魔法方法、特性和迭代器
  7. 面向视频的全新AI架构 —— 阿里云智能视觉技术全解
  8. stm32c语言写数码管定时器,使用TIM1产生1秒定时控制数码管显示0-9(STM32_10)
  9. Python 中list中所有值加和_Python 中去除列表中重复元素的5种方法
  10. DirectX 基础学习系列5 纹理映射
  11. 云桌面优缺点_云桌面中VDI架构有什么优势和劣势?
  12. mac电脑用计算机名共享打印机,苹果电脑怎么连接共享打印机_苹果电脑连接共享打印机的具体教程-系统城...
  13. 番外篇--1. 简历优化
  14. Android App开发动画特效中插值器和估值器的讲解以及利用估值器实现弹幕动画实战(附源码和演示视频 可直接使用)
  15. 京东数据分析工具推荐(京东第三方数据平台)
  16. JS 根据date日期格式返回周几
  17. iOS UITextField设置数字键盘
  18. 7. Mayavi入门
  19. 电脑数据迁移高招,怎么把旧电脑的数据迁移到新电脑
  20. 归并排序(C语言简单实现)

热门文章

  1. Redis 分布式算法原理
  2. kotlin和java区别!Android平台HTTPS抓包解决方案及问题分析,大厂面试题汇总
  3. Linux操作系统学习笔记(十)内存管理之内存映射
  4. 堡垒机的主要功能是什么?为什么需要堡垒机?
  5. 百色靖西18万亩水稻 国稻种芯·中国水稻节:广西进入收割期
  6. MATLAB利用仿射变换实现图像的缩放,旋转,剪切,平移操作
  7. 爱运动的人身体都不差----基于墨刀原型工具的健康软件设计
  8. cleanmymac废纸篓垃圾桶模块主要功能介绍
  9. 怎样将PDF水印删除 PDF删除水印的小技巧
  10. java中如果int类型超出了它的范围