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

    控件出处 https://components.xamarin.com/ https://components.xamarin.com/gettingstarted/ZumeroDataGrid/tr ...

  2. Android 实现ActionBar定制

    我们在使用Android手机时,经常发现应用中的ActionBar和我们平时使用的ActionBar相差非常大.简单的说就是,其他应用的 ActionBar为什么那么绚丽,自己应用的ActionBar ...

  3. 【Linux】部署apache

    部署前的准备: 1.安装apr #wget http://mirror.bit.edu.cn/apache/apr/apr-1.4.8.tar.gz #tar -zxvf apr-1.4.8.tar. ...

  4. java基础知识(二)

    java的布局管理: borderLayout:则将板块分为东西南北中五个方向,每添加一个组件就要指定组件摆放的方位,放置在东西南北四个方向的组件将贴边放置.当拉大Frame的时候,处在center( ...

  5. Highcharts教程

    Highcharts特性: 兼容性 - 支持所有主流浏览器和移动平台(android.iOS等). 多设备 - 支持多种设备,如手持设备 iPhone/iPad.平板等 免费使用 - 开源免费 轻量 ...

  6. java中jvm的工作原理

    首先我们安装了jdk和jre,但是jdk是为java软件开发工程师而使用的开发工具,我们运行java项目只要含有jre文件即可.对于jvm是内存分配的一块区域,我们知道,当我们开始使用java命令时, ...

  7. Win8.1OS64位oracle11安装配置及PL/SQL Developer怎样连接64位oracle

    Oracle 为什么选择oracle 1.oracle可以在主流的平台上执行,而相对于sql server仅仅支持windows,而windows在wr手里攥着呢,所以你懂的.在安全性上来讲,非常多地 ...

  8. 大到可以小说的Y组合子(一)

    问:上回乱扯淡了一通,这回该讲正题了吧. 答:OK. 先来列举一些我参考过,并从中受到启发的文章. (1.)老赵的一篇文章:使用Lambda表达式编写递归函数 (2.)装配脑袋的两篇文章:VS2008 ...

  9. Java基础知识强化51:经典排序之桶排序(BucketSort)

    1. 首先说明三点: (1)桶排序是稳定的 (2)桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 (3)桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法 2. 桶排序的分析 ...

  10. Java基础知识强化39:StringBuffer类之StringBuffer的删除功能

    1. StringBuffer的删除功能: public StringBuffer  deleteCharAt(int index):删除指定位置的字符,并返回字符串缓冲区本身. public Str ...