• 10.4-1 那棵树就长成下面这个样子
  /*1812       107    4   2    215*/
  • 下面就借用10.4-1提供的数据,构建一棵树,然后分别对它做10.4-2所要求的递归遍历和10.4-3所要求的非递归遍历。

    递归遍历的方式有三种,前序、中序、后序,实现上的差异,无非是把Traverse1(Index)函数里后三句的顺序换一换。

    非递归遍历,简单的算法是借助一个栈或者队列,同样有前序、中序、后序形式。复杂一些的算法就是下面的10.4-5。

  • 10.4-5要求实现一种非递归的遍历方法,且除了树本身外,只使用固定存储空间。

    反思一下为什么Traverse2需要使用O(n)的额外存储空间呢?那是因为一个Node出栈的同时,最多情况下,会向栈中压入左右孩子两个新节点,所以栈的空间是呈线性增长的。如果要限制存储空间为常量,就必须放弃“通过一个旧节点找到两个新节点”的做法,取而代之以“用一个旧节点找到一个新节点”的做法。

    于是就有了下面的问题,一方面,每个节点的职责是保证自己的两个孩子都被遍历到,另一方面,受到存储的限制,通过当前节点只可以找出一个新节点,,怎么办呢?只好先找左孩子,再通过左孩子找自己,然后再通过自己找右孩子(左右顺序无所谓,先右再左也一样)。所以,整个过程中当前节点指针的行走方向一共有三种状态,1.从父亲找到的自己;2. 从左孩子找到的自己 3. 从右孩子找到的自己。每种状态下当前节点该做的工作是不一样的。具体实现见Traverse3。

#include <iostream>
#include <stack>
using namespace std;class BinaryTree
{
public:using Index = int;BinaryTree();//O(n)-time recursive traverse 10.4-2void Traverse1() const;void Traverse1(Index root) const;//O(n)-time nonrecursive traverse10.4-3void Traverse2() const;//O(n)-time nonrecursive traverse,with constant extra space 10.4-5void Traverse3() const;
private:struct Node{int key;Index parent;Index left;Index right;};Node m_array[11];Index m_root;
};BinaryTree::BinaryTree()
{m_root = 6;m_array[1] = Node{12,6,7,3};m_array[3] = Node{4,1,10,-1};m_array[4] = Node{10,6,5,9};m_array[5] = Node{2,4,-1,-1};m_array[6] = Node{18,-1,1,4};m_array[7] = Node{7,1,-1,-1};m_array[9] = Node{21,4,-1,-1};m_array[10] = Node{5,3,-1,-1};
}void BinaryTree::Traverse1() const
{Traverse1(m_root);
}
void BinaryTree::Traverse1(Index root) const
{if(root == -1)return;cout << m_array[root].key << "\t";Traverse1(m_array[root].left);Traverse1(m_array[root].right);
}void BinaryTree::Traverse2() const
{stack<Index> indexStack;indexStack.push(m_root);int index,childIndex;while(!indexStack.empty()){index = indexStack.top();indexStack.pop();cout << m_array[index].key << "\t";childIndex = m_array[index].right;if(childIndex != -1)indexStack.push(childIndex);childIndex = m_array[index].left;if(childIndex != -1)indexStack.push(childIndex);}
}void BinaryTree::Traverse3() const
{enum{Parent,Left,Right};int   come_from = Parent;Index index_next = m_root,index;bool  back_to_parent;while(true){index = index_next;back_to_parent = false;if(come_from == Parent)        //从父亲找到自己,我的任务是打印自身,然后优先找可能存在的左孩子{cout << m_array[index].key << "\t";index_next = m_array[index].left;if(index_next == -1)index_next = m_array[index].right;if(index_next == -1)back_to_parent = true;}else if(come_from == Left)    //从左孩子返回到自己,我的任务是找可能存在的右孩子{index_next = m_array[index].right;come_from = Parent;if(index_next == -1)back_to_parent = true;}else                                    //从右孩子返回到自己,我的任务是返回到我的父亲{back_to_parent = true;}if(back_to_parent){index_next = m_array[index].parent;if(index_next == -1)break;if(m_array[index_next].left == index)come_from = Left;elsecome_from = Right;}}}void Test()
{BinaryTree tree;tree.Traverse1(); //18  12  7   4   5   10  2   21cout << endl;tree.Traverse2(); //18  12  7   4   5   10  2   21cout << endl;tree.Traverse3();
}
/* 调用Test,运行结果为
18  12  7   4   5   10  2   21
18  12  7   4   5   10  2   21
18  12  7   4   5   10  2   21*/

转载于:https://www.cnblogs.com/meixiaogua/p/9792710.html

二叉树的遍历 《算法导论》10.4-1~10.4-3 10.4-5相关推荐

  1. 二叉树的遍历(算法导论第三版12.1-4)(包含先序遍历,后序遍历和中序遍历)

    二叉树的遍历(算法导论第三版12.1-4) 1⃣️先序遍历 template<typename T> void preorder_tree_wald(BinaryTreeNode<T ...

  2. 重拾算法(3)——用458329个测试用例全面测试二叉树和线索二叉树的遍历算法

    重拾算法(3)--用458329个测试用例全面测试二叉树和线索二叉树的遍历算法 在"上一篇"和"上上一篇"中,我给出了二叉树和线索二叉树的遍历算法.给出算法容易 ...

  3. 【swjtu】数据结构实验6_二叉树的遍历算法

    实验内容及要求: 编写程序,用先序递归遍历法建立二叉树的二叉链表存储结构,然后输出其先序.中序.后序以及层次遍历结点访问次序.其中层次遍历的实现需使用循环队列.二叉树结点数据类型建议选用字符类型. 实 ...

  4. html二叉树遍历,二叉树的遍历算法

    二叉树的遍历算法 概述 二叉树作为一个基础的数据结构,遍历算法作为一个基础的算法,两者结合当然是经典的组合了.很多题目都会有 ta 的身影,有直接问二叉树的遍历的,有间接问的.比如要你找到树中满足条件 ...

  5. Python实现: 常用排序算法 二叉树的遍历算法

    转载自:http://www.cnblogs.com/alex3714/articles/5474411.html点击打开链接,感谢原作者,如有侵权,联系删除 本节内容 算法定义 时间复杂度 空间复杂 ...

  6. 二叉树的遍历算法(三级)

    知道二叉树在计算机里面是怎么存储的,有顺序存储结构,采用数组存储,也有链式存储结构,采用二叉链表,或者采用三叉链表,那采用链式存储结构更多一点,下面我们会讲二叉树在计算机里的实现,就是链式存储结构的二 ...

  7. 二叉树的遍历算法(一 递归算法)

    > 引言 通过递归的方式,实现遍历每一个元素的目的. 该算法分成三种除访问节点时机不同外,其他完全相同(访问路径完全相同)的算法(稍后作解释).分别为先序遍历(DLR),中序遍历(LDR),后序 ...

  8. 二叉树层次遍历算法 python_二叉树的遍历详解:前、中、后、层次遍历(Python实现)...

    二叉树的遍历详解:前.中.后.层次遍历(Python实现) 二叉树是一种常见的数据结构,而它的常见遍历方法有前序遍历.中序遍历.后续遍历.层次遍历--掌握这几种遍历方法是很有必要的. 假设我们二叉树节 ...

  9. 数据结构(二十)二叉树的递归遍历算法

    一.二叉树的遍历的定义 1.二叉树的遍历(traversing binary tree)是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问依次且仅被访问依次.树的结点之间不存在 ...

  10. 树:二叉树的层序遍历算法(超简洁实现及详细分析)

    实现思路 我们来看看下图的二叉链表 如何实现层序遍历. 层序遍历顺序:ABECDG A为B.E的双亲结点,遍历顺序是 根->左->右 是不是. 而且每个结点都是这样的遍历顺序 有木有.那么 ...

最新文章

  1. SpringBoot @Cacheable自定义KeyGenerator
  2. IoT -- (二) 物联网传感器介绍
  3. 区块链企业级解决方案 ( Hyperledger )
  4. 持续集成工具集之四 Jenkins+Maven+Git+Tomcat 项目构建和自动部署
  5. 会场安排(nyoj14)
  6. mysql查询不确定的信息_mysql-非常复杂的查询,不确定是否可行.涉及...
  7. MySQL集群架构-DRBD+headbeat +lvs+keepalived
  8. action中的动态方法调用
  9. C++标准库分析总结(一)
  10. 【Java实例】简单彩票程序
  11. 为什么对抗生成网络(GAN)被誉为过去20年来深度学习中最酷的想法?
  12. 淘宝Hadoop作业平台宙斯(zeus)开源
  13. 两个RGBA四通道颜色的叠加计算方法与代码实现
  14. Web在线打印设计器即将推出,像Excel一样在线设计模板
  15. 检测xposed框架实现
  16. [RK3399]触摸屏汇顶gt9xx调试
  17. 罗杰波、马毅、华刚等谈视觉研究那些事:是时候重新定义视觉了
  18. 贵阳经开区管委会考察团到访数澜科技,共探城市数据运营解决方案
  19. Matlab完整教程专栏完整目录
  20. OrCAD: Capture CIS中两个重要概念:instance 和 occurrences

热门文章

  1. pvr转png工具_pngtosvg 一个神奇的在线工具
  2. 不支持给定路径的格式_剑指offer_12_矩阵中的路径
  3. mysql5.7多源复制缺点_配置mysql5.7多源复制
  4. 华中师范大学邮箱matlab,正版软件管理与服务平台(华中师范大学)
  5. 20多个Maven命令和选项(备忘单)
  6. java 8 谓词_Java谓词– Java 8谓词
  7. mapreduce代码示例_MapReduce算法示例
  8. jsf集成spring_JSF Spring Hibernate集成示例教程
  9. Akka创建第一个Actor《nine》译
  10. RT-Thread源码学习第六篇,线程调度器(1)