二叉树的Morris遍历
二叉树的遍历,除了上篇文章中的传统递归和使用的栈结构的非递归方式,还有如下这种Morris遍历方式,该算法的构思非常巧妙:利用前驱空闲的rightChild指针指向当前节点,形成一个环。时间复杂度和前面两种一样,还是O(n),但是空间复杂度由O(n)直接下降到了O(1)。代码如下:
/*************************************************************************
> File Name: MorrisTraversal.c
> Description: 线索二叉树的实现
> Author: Yves
> E-mail:
> Created Time: 2015-5-23. 22:51:16
************************************************************************/ #include <stdio.h>
#include <stdlib.h> typedef char ElemType;
typedef struct tagBiTreeNode
{
ElemType data;
struct tagBiTreeNode* leftChild;
struct tagBiTreeNode* rightChild;
}BiTreeNode, *pBiTreeNode;//指向BiTNode的指针 static void CreatBiTree(pBiTreeNode *root);//创建二叉树
static void PreOrderMorrisTraversal(pBiTreeNode root);//前序Morris遍历
static void InOrderMorrisTraversal(pBiTreeNode root);//中序Morris遍历
static void PostOrderMorrisTraversal(pBiTreeNode root);//后序Morris遍历 pBiTNode pre; int main(void)
{
pBiTreeNode root;
printf("Please input the node of the tree(preorder sequence): ");
CreatBiTree(&root);
printf("Traverse the tree in PreOrderMorrisTraversal\n");
PreOrderMorrisTraversal(root);
printf("Traverse the tree in InOrderMorrisTraversal\n");
InOrderMorrisTraversal(root);
printf("Traverse the tree in PostOrderMorrisTraversal\n");
PostOrderMorrisTraversal(root) return ;
} static void CreatBiTree(pBiTreeNode *root)
{
ElemType c;
scanf("%c",&c);
if(c == '#')
{
*root = NULL;
}else
{
*root = (pBiTreeNode)malloc(sizeof(BiTreeNode));
(*root)->data = c;
CreatBiTree(&(*root)->leftChild);
CreatBiTree(&(*root)->rightChild);
}
} static void PreOrderMorrisTraversal(pBiTreeNode root)
{
if(root == NULL)
{
return;
}
pBiTreeNode cur,pre,temp;
cur = root;
while(cur != NULL)
{
if(!cur->leftChild)
{
printf("%c ", cur->data);
pre = cur;
cur = cur->rightChild;
}else
{
for(temp = cur->leftChild; temp->rightChild != NULL && temp->rightChild != cur; temp = temp->rightChild);
if(temp->rightChild == NULL)
{
temp->rightChild = cur;
printf("%c ", cur->data);
pre = cur;
cur = cur->leftChild;
}else
{ temp->rightChild = NULL;
cur = cur->rightChild;
}
}
}
} static void InOrderMorrisTraversal(pBiTreeNode root)
{
if(root == NULL)
{
return;
}
pBiTreeNode cur,pre,temp;
cur = root;
while(cur != NULL)
{
if(!cur->leftChild)
{
printf("%c ", cur->data);
pre = cur;
cur = cur->rightChild;
}else
{
for(temp = cur->leftChild; temp->rightChild != NULL && temp->rightChild != cur; temp = temp->rightChild);
if(temp->rightChild == NULL)
{
temp->rightChild = cur;
cur = cur->leftChild;
}else /*Meaning the left tree has been accessed completely.*/
{
printf("%c ", cur->data);
temp->rightChild = NULL;
pre = cur;
cur = cur->rightChild;
}
}
}
} static void PostOrderMorrisTraversal(pBiTreeNode root)
{
//coding
}
二叉树的Morris遍历的更多相关文章
- 【数据结构与算法】二叉树的 Morris 遍历(前序、中序、后序)
前置说明 不了解二叉树非递归遍历的可以看我之前的文章[数据结构与算法]二叉树模板及例题 Morris 遍历 概述 Morris 遍历是一种遍历二叉树的方式,并且时间复杂度O(N),额外空间复杂度O(1 ...
- Morris 遍历实现二叉树的遍历
Morris 遍历实现二叉树的遍历 作者:Grey 原文地址: 博客园:Morris 遍历实现二叉树的遍历 CSDN:Morris 遍历实现二叉树的遍历 说明 Morris 遍历可以实现二叉树的先,中 ...
- 二叉树的遍历(递归,迭代,Morris遍历)
二叉树的三种遍历方法: 先序,中序,后序,这三种遍历方式每一个都可以用递归,迭代,Morris三种形式实现,其中Morris效率最高,空间复杂度为O(1). 主要参考博客: 二叉树的遍历(递归,迭代, ...
- 二叉树的遍历(递归,迭代,Morris遍历)
二叉树的遍历: 先序,中序,后序: 二叉树的遍历有三种常见的方法, 最简单的实现就是递归调用, 另外就是飞递归的迭代调用, 最后还有O(1)空间的morris遍历: 二叉树的结构定义: struct ...
- 【转载】Morris遍历二叉树 & BST(二叉搜索树) Traverse & 空间O(1) 时间O(n)
因为做一道Leetcode的题目(前面博客有:link),需要用Space O(1)空间复杂度来中序遍历树, 看了Discuss,也上网搜了一下,发现空间O(1)可以用 Morris遍历的方法.方法介 ...
- 面试中很值得聊的二叉树遍历方法——Morris遍历
Morri遍历 通过利用空闲指针的方式,来节省空间.时间复杂度O(N),额外空间复杂度O(1).普通的非递归和递归方法的额外空间和树的高度有关,递归的过程涉及到系统压栈,非递归需要自己申请栈空间,都具 ...
- 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序
接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...
- 经典算法 Morris遍历
内容: 1.什么是morris遍历 2.morris遍历规则与过程 3.先序及中序 4.后序 5.morris遍历时间复杂度分析 1.什么是morris遍历 关于二叉树先序.中序.后序遍历的递归和非递 ...
- Morris遍历
Morris遍历 一种遍历二叉树的方式,并且时间复杂度O(N),额外空间复杂度O(1) 通过利用原树中大量空闲指针的方式,达到节省空间的目的 Morris遍历可以改前中后序的树遍历 思路: 创建一个当 ...
随机推荐
- 一句话输出NGINX日志访问IP前十位排行
AWK的数组字段自增加,然后取值的方法,要记得哟. 还有,SORT指定列排行,也常用的.
- 17 个 Linux 下用于 C/C++ 的最好的 IDE
C++,一个众所周知的 C 语言的扩展,是一个优秀的.强大的.通用编程语言,它能够提供现代化的.通用的编程功能,可以用于开发包括视频游戏.搜索引擎.其他计算机软件乃至操作系统等在内的各种大型应用. C ...
- 【HDOJ】1406 Ferry Loading III
模拟,注意需要比较队头与当前时间的大小关系. #include <cstdio> #include <cstring> #include <cstdlib> #de ...
- 【转】C语言文件操作解析(三)
原文网址:http://www.cnblogs.com/dolphin0520/archive/2011/10/07/2200454.html C语言文件操作解析(三) 在前面已经讨论了文件打开操作, ...
- 2014-07-29 浅谈MVC框架中Razor与ASPX视图引擎
今天是在吾索实习的第15天.随着准备工作的完善,我们小组将逐步开始手机端BBS的开发,而且我们将计划使用MVC框架进行该系统的开发.虽然我们对MVC框架并不是非常熟悉,或许这会降低我们开发该系统的效率 ...
- 关于本学期西南交通大学ACM-ICPC校集训队 训练计划(Beta 1.0)
在第十周新秀杯之后,从第十一周起的训练计划如下: 1.十一周的周一至周五进行ACM校集训队申请.申请方式从2014年11月17日0:00开始,发送申请者的姓名.学号.专业.电话.QQ以及大学(针对大一 ...
- css和js引用图片的路径问题
原文转自:http://www.cnblogs.com/azumia/archive/2012/06/17/2552346.html 在JS文件中书写相对路径:JS文件是指在页面中引用的外部JavaS ...
- [Flask]学习Flask第三天笔记总结
from flask import Flask,render_template,request from others import checkLogin app = Flask(__name__) ...
- license文件生成原理
byte解密weblogic加密oraclehex 现在很多J2EE应用都采用一个license文件来授权系统的使用,特别是在系统购买的早期,会提供有限制的license文件对系统进行限制,比如试 ...
- Mysql相关操作
1. 如何更改系统环境变量PATH?vim /etc/profile 加入 PATH=$PATH:/usr/local/mysql/bin2. 默认mysql安装好后,并没有root密码,如何给ro ...