算法9---二叉树的遍历不用栈和递归

二叉树的遍历不用栈和递归

转自:ACM之家 http://www.acmerblog.com/inorder-tree-traversal-without-recursion-and-without-stack-5988.html
我们知道,在深度搜索遍历的过程中,之所以要用递归或者是用非递归的栈方式,参考二叉树非递归中序遍历,都是因为其他的方式没法记录当前节点的parent,而如果在每个节点的结构里面加个parent 分量显然是不现实的,那么Morris是怎么解决这一问题的呢?好吧,他用得很巧妙,实际上是用叶子节点的空指针来记录当前节点的位置,然后一旦遍历到了叶子节点,发现叶子节点的右指针指向的是当前节点,那么就认为以当前节点的左子树已经遍历完成。Morris 遍历正是利用了线索二叉树 的思想。
以inorder为例,初始化当前节点为root,它的遍历规则如下:
- 如果当前节点为空,程序退出。
- 如果当前节点非空,
- 如果当前节点的左儿子为空,那么输出当前节点,当前节点重置为当前节点的右儿子。
- 如果当前节点的左儿子非空,找到当前节点左子树的最右叶子节点(此时最右节点的右儿子有两种情况,一种是指向当前节点,一种是为空,你也许感到奇怪,右节点的右儿子怎么可能非空,注意,这里的最右叶子节点只带的是原树中的最右叶子节点。),若其最右叶子节点为空,令其指向当前节点,将当前节点重置为其左儿子,若其最右节点指向当前节点,输出当前节点,将当前节点重置为当前节点的右儿子,并恢复树结构,即将最右节点的右节点再次设置为NULL
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 struct tNode
 5 {
 6    int data;
 7    struct tNode* left;
 8    struct tNode* right;
 9 };
10 
11 void MorrisTraversal(struct tNode *root)
12 {
13   struct tNode *current,*pre;
14 
15   if(root == NULL)
16      return; 
17 
18   current = root;
19   while(current != NULL)
20   {                 
21     if(current->left == NULL)
22     {
23       printf(" %d ", current->data);
24       current = current->right;      
25     }    
26     else
27     {
28       /* 找到current的前驱节点 */
29       pre = current->left;
30       while(pre->right != NULL && pre->right != current)
31         pre = pre->right;
32 
33       /* 将current节点作为其前驱节点的右孩子 */
34       if(pre->right == NULL)
35       {
36         pre->right = current;
37         current = current->left;
38       }
39 
40       /* 恢复树的原有结构,更改right 指针 */   
41       else 
42       {
43         pre->right = NULL;
44         printf(" %d ",current->data);
45         current = current->right;      
46       } /* End of if condition pre->right == NULL */
47     } /* End of if condition current->left == NULL*/
48   } /* End of while */
49 }
50 
51 struct tNode* newtNode(int data)
52 {
53   struct tNode* tNode = (struct tNode*)
54                        malloc(sizeof(struct tNode));
55   tNode->data = data;
56   tNode->left = NULL;
57   tNode->right = NULL;
58 
59   return(tNode);
60 }
61 
62 /* 测试*/
63 int main()
64 {
65 
66   /* 构建树结构如下:
67             1
68           /   \
69         2      3
70       /  \
71     4     5
72   */
73   struct tNode *root = newtNode(1);
74   root->left        = newtNode(2);
75   root->right       = newtNode(3);
76   root->left->left  = newtNode(4);
77   root->left->right = newtNode(5); 
78 
79   MorrisTraversal(root);
80    return 0;
81 }

 

转载于:https://www.cnblogs.com/tao-alex/p/5894348.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python调用摄像头人脸识别代码_利用face_recognition,dlib与OpenCV调用摄像头进行人脸识别...

用已经搭建好 face_recognition&#xff0c;dlib 环境来进行人脸识别 未搭建好环境请参考&#xff1a; 使用opencv 调用摄像头 import face_recognition import cv2 video_capture cv2.videocapture(0) # videocapture打开摄像头&#xff0c;0为笔记本内置摄像头&#xff0c;1…

python列表批量 修改_python实现多进程按序号批量修改文件名的方法示例

本文实例讲述了python实现多进程按序号批量修改文件名的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;说明文件名命名方式如图&#xff0c;是数字序号开头&#xff0c;但是中间有些文件删掉了&#xff0c;序号不连续&#xff0c;这里将序号连续起来&#xff0c;…

Struts1 tag

标签库&#xff1a; a) struts框架下的struts标签库 b) sun jstl c标签库 作用: 1) jsp 和 java代码分离 -- 自定义标签 用标签来替代Java的代码 2) struts标签 能够和struts-config.xml actionForm等特有的对象进行交互 stru…

“multiprocessing\spawn.py”, line 105, in spawn_main错误与解决方法

记录一个不知名的错误错误解决方法OS&#xff1a; Windows 10 错误非常的长&#xff0c;以至于&#xff0c;我也没有什么耐心去看&#xff0c;看了前面几行&#xff0c;应该是多线程引起的。下面太长&#xff0c;可以选择不看。 错误 Traceback (most recent call last): Trac…

hpunix下11gRac的安装

一.检查环境 1.操作系统版本# uname -a 2.补丁包三大补丁包#swlist -l bundle|grep QPKAPPS#swlist -l bundle|grep QPKBASE#swlist -l bundle|grep HWEnable11i #swlist -l patch -a supersedes|grep PHKL_XXXXX检查是否已有或是已被替代For HP-UX 11i V3 (11.31): PHCO_40381…

【转】彻底搞清计算结构体大小和数据对齐原则

数据对齐: 许多计算机系统对基本数据类型合法地址做出了一些限制&#xff0c;要求某种类型对象的地址必须是某个值K(通常是2&#xff0c;4或8)的倍数。这种对齐限制简化了形成处理器和存储器系统之间的接口的硬件设计。例如&#xff0c;假设一个处理器总是从存储器中取出8个字节…

python里pip是什么意思_python使用pip的方法是什么

python使用pip的方法是什么 发布时间&#xff1a;2020-08-25 11:51:08 来源&#xff1a;亿速云 阅读&#xff1a;104 作者&#xff1a;小新 小编给大家分享一下python使用pip的方法是什么&#xff0c;相信大部分人都还不怎么了解&#xff0c;因此分享这篇文章给大家参考一下&am…

Pytorch 学习率衰减 之 余弦退火与余弦warmup 自定义学习率衰减scheduler

学习率衰减&#xff0c;通常我们英文也叫做scheduler。本文学习率衰减自定义&#xff0c;通过2种方法实现自定义&#xff0c;一是利用lambda&#xff0c;另外一个是继承pytorch的lr_scheduler import math import matplotlib.pyplot as plt import numpy as np import torch i…

c++ 字符串赋给另一个_7.2 C++字符串处理函数

点击上方“C语言入门到精通”&#xff0c;选择置顶第一时间关注程序猿身边的故事作者闫小林白天搬砖&#xff0c;晚上做梦。我有故事&#xff0c;你有酒么&#xff1f;C字符串处理函数C语言和C提供了一些字符串函数&#xff0c;使得用户能很方便地对字符串进行处理。这些是放在…

如何检测远程主机上的某个端口是否开启

有时候我们要测试远程主机上的某个端口是否开启&#xff0c;无需使用太复杂的工作&#xff0c;windows下就自带了工具&#xff0c;那就是telnet。怎么检测呢&#xff0c;按下面的步骤&#xff1a; 1、安装telnet。我的win7下就没有telnet&#xff0c;在cmd下输入telnet提示没有…

Windows10 + WSL (Ubuntu) + Anaconda + vscode 手把手配置python运行环境(含虚拟环境)

配置WSL windows桌面下&#xff0c;按下面顺序可以找到 "启动或关闭windows功能” &#xff0c; 开始 -> 设置 -> 应用 -> 应用和功能 -> 可选功能 -> 相关设置下 更多Windows功能&#xff08;滚动鼠标到底部&#xff09;点击后&#xff0c;会弹出 启动或…

Inline函数使用注意事项

Inline函数使用注意事项 1.在一个文件中定义的inline函数不能再另一个文件中使用 2.inline函数应简洁&#xff0c;只有少数几个语句。 3.在inline函数中不能有循环&#xff0c;if&#xff0c;switch语句。 4.inline函数要在调用和声明前定义&#xff01;&#xff01;&#xff0…

2019编译ffepeg vs_如何在windows10下使用vs2017编译最新版本的FFmpeg和ffplay

该文章描述了如何在windows10 64位系统下面编译出FFmpeg的库及其自带的ffplay播放器&#xff0c;而且全部采用最新的版本&#xff0c;这样我们可以在vs2017的ide下调试ffplay&#xff0c;能使我们更容易学习FFmpeg的架构以及音视频播放器的原理。步骤&#xff1a;1.安装vs2017在…

训练集山准确率高测试集上准确率很低_推荐算法改版前的AB测试

编辑导语&#xff1a;所谓推荐算法就是利用用户的一些行为&#xff0c;通过一些数学算法&#xff0c;推测出用户可能喜欢的东西&#xff1b;如今很多软件都有这样的操作&#xff0c;对于此系统的设计也会进行测试&#xff1b;本文作者分享了关于推荐算法改版前的AB测试&#xf…

C#实现渐变颜色的Windows窗体控件

C#实现渐变颜色的Windows窗体控件! 1,定义一个BaseFormGradient,继承于System.Windows.Forms.Form2,定义三个变量: privateColor _Color1 Color.Gainsboro; privateColor _Color2 Color.White; privatefloat_ColorAngle 0f;3,重载OnPaintBackground方法 protecte…

ios7开发学习笔记-包括c oc 和ios介绍

请查看我的新浪资料分享 http://iask.sina.com.cn/u/2430843520 转载于:https://www.cnblogs.com/langtianya/p/3708298.html

Windows下 jupyter notebook 运行multiprocessing 报错的问题与解决方法

文章目录测试用的代码错误解决方法测试用的代码 下面每一个对应一个jupyter notebook的单元格 import time from multiprocessing import Process, Queuedef generator():c 0while True:time.sleep(1.0) # read somethingyield cc 1%%timeds generator() for i in range(3…

如何将javaweb项目部署到linux下

以下是对将javaweb项目部署到linux下的方法进行了详细的分析介绍一般都在windows下开发的现在部署到linux下将项目达成war包(用eclipse项目右键>Export>选择war file)将tomcat(用winSCP当然你也可以用secureCRT用securCRT需要建立sftp(即上传文件的目录)用put tomcat命令…

vc mysql_vc6.0连接mysql数据库

一、MySQL的安装Mysql的安装去官网下载就可以。。。最新的是5.7版本。。二、VC6.0的设置(1)打开VC6.中选0 工具栏Tools菜单下的Options选项&#xff0c;在Directories的标签页中右边的“Show directories for:”下拉列表中“Includefiles”&#xff0c;然后在中间列表框中添加你…

python class用法_python原类、类的创建过程与方法

【小宅按】今天为大家介绍一下python中与class 相关的知识……获取对象的类名python是一门面向对象的语言&#xff0c;对于一切接对象的python来说&#xff0c;咱们有必要深入的学习与了解一些知识首先大家都知道&#xff0c;要获取一个对象所对应的类&#xff0c;需要使用clas…