二叉树的遍历,除了上篇文章中的传统递归和使用的栈结构的非递归方式,还有如下这种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遍历的更多相关文章

  1. 【数据结构与算法】二叉树的 Morris 遍历(前序、中序、后序)

    前置说明 不了解二叉树非递归遍历的可以看我之前的文章[数据结构与算法]二叉树模板及例题 Morris 遍历 概述 Morris 遍历是一种遍历二叉树的方式,并且时间复杂度O(N),额外空间复杂度O(1 ...

  2. Morris 遍历实现二叉树的遍历

    Morris 遍历实现二叉树的遍历 作者:Grey 原文地址: 博客园:Morris 遍历实现二叉树的遍历 CSDN:Morris 遍历实现二叉树的遍历 说明 Morris 遍历可以实现二叉树的先,中 ...

  3. 二叉树的遍历(递归,迭代,Morris遍历)

    二叉树的三种遍历方法: 先序,中序,后序,这三种遍历方式每一个都可以用递归,迭代,Morris三种形式实现,其中Morris效率最高,空间复杂度为O(1). 主要参考博客: 二叉树的遍历(递归,迭代, ...

  4. 二叉树的遍历(递归,迭代,Morris遍历)

    二叉树的遍历: 先序,中序,后序: 二叉树的遍历有三种常见的方法, 最简单的实现就是递归调用, 另外就是飞递归的迭代调用, 最后还有O(1)空间的morris遍历: 二叉树的结构定义: struct ...

  5. 【转载】Morris遍历二叉树 & BST(二叉搜索树) Traverse & 空间O(1) 时间O(n)

    因为做一道Leetcode的题目(前面博客有:link),需要用Space O(1)空间复杂度来中序遍历树, 看了Discuss,也上网搜了一下,发现空间O(1)可以用 Morris遍历的方法.方法介 ...

  6. 面试中很值得聊的二叉树遍历方法——Morris遍历

    Morri遍历 通过利用空闲指针的方式,来节省空间.时间复杂度O(N),额外空间复杂度O(1).普通的非递归和递归方法的额外空间和树的高度有关,递归的过程涉及到系统压栈,非递归需要自己申请栈空间,都具 ...

  7. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  8. 经典算法 Morris遍历

    内容: 1.什么是morris遍历 2.morris遍历规则与过程 3.先序及中序 4.后序 5.morris遍历时间复杂度分析 1.什么是morris遍历 关于二叉树先序.中序.后序遍历的递归和非递 ...

  9. Morris遍历

    Morris遍历 一种遍历二叉树的方式,并且时间复杂度O(N),额外空间复杂度O(1) 通过利用原树中大量空闲指针的方式,达到节省空间的目的 Morris遍历可以改前中后序的树遍历 思路: 创建一个当 ...

随机推荐

  1. Altium Designer(Protel)网络连接方式Port和Net Label详解

    1.图纸结构      图纸包括两种结构关系: 一种是层次式图纸,该连接关系是纵向的,也就是某一层次的图纸只能和相邻的上级或下级有关系:另一种是扁平式图纸,该连接关系是横向的,任何两张图纸之间都可以建 ...

  2. HDOJ 1164 Eddy's research I(拆分成素数因子)

    Problem Description Eddy's interest is very extensive, recently he is interested in prime number. Ed ...

  3. HDU_2019——向排序好的数列中插入数

    Problem Description 有n(n<=100)个整数,已经按照从小到大顺序排列好,现在另外给一个整数x,请将该数插入到序列中,并使新的序列仍然有序.   Input 输入数据包含多 ...

  4. cocos 的CCScheduler模块

    scheduleSelector函数->查找m_pHashForTimers是否有存储回调的Obj类实例,否,创建新条目tHashTimerEntry,指向回调类实例,tHashTimerEnt ...

  5. Shell中变量的使用

    1.变量的声明 name="blacksonny" 注意://变量定义时不加$,变量与等号之间不能有空格 变量命名规则: 首个字符必须为字母(a-z,A-Z). 中间不能有空格,可 ...

  6. 【BUG】Kewastunpackstats(): Bad Magic 1 (0x。。。。, 0)

    Kewastunpackstats(): Bad Magic 1 (0x1108f7b87, 0) In Alert Logfile After Upgrading to 11.2.0.1 Appli ...

  7. Python 线程池的原理和实现及subprocess模块

    最近由于项目需要一个与linux shell交互的多线程程序,需要用python实现,之前从没接触过python,这次匆匆忙忙的使用python,发现python确实语法非常简单,功能非常强大,因为自 ...

  8. Spring注解的使用和区别:@Component、@Service、@Repository、@Controller

    Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository.@Service 和 @Controller.在目前的 Spring ...

  9. linux file命令

    1. file 是检测文件类型的命令.2. 文件类型就文件组织的方式,通常不同的文件类型执行不同的标准.例如我们熟知的:txt , doc , xls , pdf ...3. file 命令的简单用法 ...

  10. 运行第一个Hadoop程序,WordCount

    系统: Ubuntu14.04 Hadoop版本: 2.7.2 参照http://www.cnblogs.com/taichu/p/5264185.html中的分享,来学习运行第一个hadoop程序. ...