10.4-5 给定一个n结点的二叉树,写出一个O(n)O(n)O(n)时间的非递归过程,将该树的每一个结点的关键字输出。要求除该树本身的存储空间外只能使用固定量的额外存储空间,且中过程中不得修改该树,即使是暂时的修改也不允许。

要完成O(1)O(1)O(1)的空间内遍历该树,需要每个结点需要能访问其父节点进行回溯。

struct Tree
{Tree *parent;Tree *left;Tree *right;int key;
};

中序遍历:

  1. 访问左孩子
  2. 访问右孩子
  3. 从左孩子返回,访问根节点,进入右孩子访问
  4. 从右孩子返回,整棵树访问完成,回溯到上层,直到当前结点为根节点或该结点是父节点的左孩子

下面是测试代码:

#include<iostream>
#include<stack>
using namespace std;
#define NIL -1
struct Tree
{Tree* left;Tree* right;Tree* parent;int key;Tree():left(nullptr),right(nullptr),parent(nullptr){}
};
void print(const Tree* t)
{cout << t->key << " ";
}
void createTree(Tree *&t)
{int key;cin >> key;if(key==NIL){t=nullptr;return;}t=new Tree();t->key=key;createTree(t->left);createTree(t->right);//存在子结点,更细父指针if(t->left)t->left->parent=t;if(t->right)t->right->parent=t;
}
// 递归版本
void inorder_travel(Tree *h)
{if(h){inorder_travel(h->left);print(h);inorder_travel(h->right);}
}// 使用stack非递归版本,结点不需要parent指针
void inorder_byStack(Tree*h)
{stack<Tree*> sta;Tree *p=h;while(p || !sta.empty()){while(p){sta.push(p);p=p->left;}p=sta.top();sta.pop();print(p);p=p->right;}
}
// 没有使用栈的版本,通过h和pre之间的关系进行遍历。
// 回溯需要parent指针。
void inorder_noStack(Tree* h)
{if(!h)return;//pre作为前驱,判断从左孩子还是右孩子返回Tree* pre=nullptr;while(true){//找到左结点if(pre!=h->left){while(h->left)h=h->left;}print(h);//存在右结点则进入if(h->right){h=h->right;continue;}//右孩子返回时,回溯直到根结点的父节点或是父节点的左孩子do{pre=h;h=h->parent;if(h==nullptr)return;}while(pre==h->right);}
}
int main()
{Tree* head;createTree(head);inorder_travel(head);cout << endl;inorder_byStack(head);cout << endl;inorder_noStack(head);
}

测试数据:
1 2 4 7 -1 -1 -1 5 8 -1 -1 -1 3 6 -1 9 -1 -1 -1

树的形状是:

中序遍历结果:
7 4 2 8 5 1 6 9 3

算法导论 练习10.4-5二叉树的遍历相关推荐

  1. 算法导论练习 10.4-5及12.1-3

    //算法导论10.4-5及12.1-3 //1. 10.4-5 //给定一个n节点的二叉树,写出一个O(n)时间的非递归过程,将该树每个节点的关键 //字输出.要求除该树本身的存储空间外只能使用固定量 ...

  2. 二叉树的遍历 《算法导论》10.4-1~10.4-3 10.4-5

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

  3. 算法导论——lec 10 图的基本算法及应用

    搜索一个图是有序地沿着图的边訪问全部定点, 图的搜索算法能够使我们发现非常多图的结构信息, 图的搜索技术是图算法邻域的核心. 一. 图的两种计算机表示 1. 邻接表: 这样的方法表示稀疏图比較简洁紧凑 ...

  4. 算法导论2nd 10.1-7

    为什么80%的码农都做不了架构师?>>>    思路:两个队列q1和q2,两个队列指针pusher和poper分别指向q1和q2,push时调用pusher->enqueue, ...

  5. 算法导论第10章习题

    10.1-1 略 10.1-2 把这个数组的头和尾各当成一个stack就好了,如果一个stack在push的过程中发现已经有值了就说明放满了. 10.1-3 略 10.1-4 ENQUE,DEQUE中 ...

  6. 带哨兵节点的链_【算法导论】10.2不带哨兵节点和带哨兵节点的双向链表

    不带哨兵节点的双向链表即一般的双向链表,有一个头指针指向第一个节点,每个节点有key值和两个指针next和pre,分别指向前后相邻的节点,头结点的pre=NULL,尾节点的next=NULL,比较明了 ...

  7. 算法导论之贪心算法(Huffman编码和拟阵)

    贪心算法,在解决最优化问题上,通过得到子问题的局部最优解来合成问题的一个解,以局部最优选择来输出一个全局最优解. 问题要用贪心算法来求解,需满足和动态规划一样的最优子结构特征,同时还需要再每个子问题最 ...

  8. 算法导论 练习12.1

    12.1-1 对于关键字集合{1,4,5,10,16,17,21}\{1,4,5,10,16,17,21\}{1,4,5,10,16,17,21},分别画出高度为2.3.4.5和6的二叉搜索树. 这里 ...

  9. 算法导论:dfs深度优先搜索算法及基于dfs的拓扑排序以及宽度优先搜索算法bfs

    1.dfs深度优先搜索算法 算法导论中是通过三种标记颜色来介绍dfs的,white代表还没被搜过,grey代表被搜了一些,还没结束,white表示已经搜索完成的状态. c/c++复现dfs代码 #in ...

最新文章

  1. 如何在window系统VS中设置boost编程环境
  2. laravel 的 表单请求
  3. python 递归 分叉_浅谈Python 递归算法指归
  4. TypeScript 的 Object Types
  5. mysql从5.5直接升级到5.7后,执行mysql_upgrade速度很慢且执行结束后数据目录大小增加一倍及 mysqlpump备份出现1577错误...
  6. 【tensorflow】tensorflow -gpu安装及jupyter环境更改
  7. Python+tkinter+pillow实现屏幕任意区域截图
  8. TensorFlow函数:tf.ones
  9. LINUX当前目录下的文件夹大小
  10. 高等数学学习笔记——第九讲——数列收敛的判定方法
  11. 在【守望先锋】学习C++的类与对象
  12. unity3d 不规则外发光描边_PS发光字体教程
  13. 显卡和CPU的关系像“主仆”,GPU的工作原理是什么
  14. epr系统服务器配置,erp系统云服务器配置要求
  15. 珠海 第十届亚洲机器人锦标赛_逾2000名选手云集珠海竞技第十届亚洲机器人锦标赛...
  16. License server system does not support this version of this feature
  17. 天球坐标系和地球坐标系
  18. java 图片检查_使用JAVA如何对图片进行格式检查以及安全检查处理
  19. 软考程序员有必要考吗?
  20. MyEclipse小结

热门文章

  1. (zt)ACE中的Proactor介绍和应用实例
  2. mysql 中ak_数据库ak
  3. TCP/UDP套接字网络协议
  4. J.U.C并发框架源码阅读(十七)ReentrantReadWriteLock
  5. Yandex.Algorithm 2011 Round 2 D. Powerful array 莫队算法
  6. Linux设备模型(4)_sysfs
  7. 微信读书App来了 小伙伴们快去占榜吧
  8. Asp.Net Mvc3.0(MEF依赖注入理论)
  9. 《恋上数据结构第1季》哈希表介绍以及从源码分析哈希值计算
  10. JZ32变形~剑指 Offer 32 - II. 从上到下打印二叉树 II