Morris
Morris
/*Morris遍历树:
*一;如果一个结点有左子树会到达此节点两次(第二次到达结点的时候左子树的所有结点都遍历完成),第一次遍历左子树最后
* 节点为nullptr,第二次遍历指向他自己
*二:否则到达一次(第一次到来和第二次到来一起 )
*当前节点cur
*1.如果cur没有左子树,cur向右移动:cur=cur->right
*2.如果cur有左结点,找左子树最右的结点记为mostRight
* 1>如果mostRight的右指针为nullptr,让其指向cur,cur向左移动:cur=cur->left
* 2>如果mostRight指向cur,让其指向nullptr,cur向右移动
*/
#include <iostream>
#include <algorithm>
#include <iterator>
#include <list>
using namespace std; typedef struct Tree
{
int value;
Tree *left,*right;
Tree()
{
value=;
left=right=nullptr;
}
}Tree;
void create_tree(Tree **root)
{
int n;
cin>>n;
if(n==)
*root=nullptr;
else
{
*root=new Tree();//*root中的内容就是地址
(*root)->value=n;
(*root)->left=nullptr;
(*root)->right=nullptr;
create_tree(&((*root)->left));
create_tree(&((*root)->right));
}
}
class Morris
{
public:
void morris_in(Tree *const root);//O(1)的空间复杂度遍历方法
void morris_pre(Tree *const root);
void morris_back(Tree *const root);
private:
void print_edge(Tree *const cur);
};
//先序中序只是选择时机的差别
void Morris::morris_pre(Tree *const root)
{
if(root==nullptr)
return; Tree *cur=root;
Tree *mostRight=nullptr;
while(cur!=nullptr)//当前节点不为nullptr继续遍历
{
mostRight=cur->left;
if(mostRight!=nullptr)//第二种情况:有左结点
{
//找当前节点左子树的最右结点
while(mostRight->right!=nullptr&&mostRight->right!=cur)
mostRight=mostRight->right; //<1>如果不指向当前节点(也就是指向nullptr,即第一次到来),就让它指向当前节点
if(mostRight->right!=cur)
{
mostRight->right=cur;
cout<<cur->value<<" ";
cur=cur->left;
continue;
}
else//<2>如果指向当前节点(也即第二次到来)把值置为nullptr
mostRight->right=nullptr;
}
else//一个结点没有左子树,第一次到来和第二次到来一起
cout<<cur->value<<" ";
//第一种情况:没有左结点向右走
cur=cur->right;
}
cout<<endl;
} //中序打印:如果一个节点有左子树,把左子树都处理完再打印自己
void Morris::morris_in(Tree *const root)
{
if(root==nullptr)
return; Tree *cur=root;
Tree *mostRight=nullptr;
while(cur!=nullptr)
{
mostRight=cur->left;
if(mostRight!=nullptr)
{
while(mostRight->right!=nullptr&&mostRight->right!=cur)
mostRight=mostRight->right; if(mostRight->right!=cur)
{
mostRight->right=cur;
cur=cur->left;
continue;
}
else
mostRight->right=nullptr;
}
//把打印时机放在最后一次来到此节点(如果结点没左子树第一次和第二次同时到来)
cout<<cur->value<<" "; //此节点要向右走,也就是左子树都处理完
cur=cur->right;
}
cout<<endl;
} //把打印时机放在第二次(该结点必须两次来到)来到该结点的时候,只关注能两次到来该节点的结点
//第二次到来时逆序打印左子树的右边界,打印完成之后在整个函数退出之前单独打印整个数的右边界
void Morris::morris_back(Tree *const root)
{
if(root==nullptr)
return; Tree *cur=root;
Tree *mostRight=nullptr;
while(cur!=nullptr)
{
mostRight=cur->left;
if(mostRight!=nullptr)//有左子树
{
while(mostRight->right!=nullptr&&mostRight->right!=cur)
mostRight=mostRight->right; if(mostRight->right!=cur)
{
mostRight->right=cur;
cur=cur->left;
continue;
}
else//第二次来到此节点
{
mostRight->right=nullptr;
print_edge(cur->left);
}
}
cur=cur->right;
}
print_edge(root);
cout<<endl;
}
void Morris::print_edge(Tree *const cur)
{
Tree *t=cur;
list<Tree *> list;
while(t!=nullptr)
{
list.push_back(t);
t=t->right;
}
list.reverse();
for(auto it=list.begin();it!=list.end();++it)
cout<<(*it)->value<<" ";
}
int main()
{
Tree *root=nullptr;
create_tree(&root); Morris ms;
ms.morris_pre(root); ms.morris_in(root); ms.morris_back(root);
return ;
}
Morris的更多相关文章
- Morris post order traversal algorithm
Sept. 5, 2015 花时间把代码读明白, 比光看书强. 动手写代码, 改代码, 兴趣是最好的老师. 多记几个例子, 增加情趣. 举个例子关于中序遍历, 4 ...
- Morris.js和flot绘制折线图的比较
[文章摘要] 最近用开源的AdminLTE做框架感觉效果特别好,其针对图表库Morris.js和flot都提供了不错的支持,也都提供了这两者的例子.不过Morris.js是基于Raphael.js来的 ...
- 一款免费的js图表工具--morris
前段时间需要使用免费的图表工具做报表,同事提及了一款图表工具morris.官方网站: http://www.oesmith.co.uk/morris.js/ 该插件遵循BSD协议,可以用于商业软件,也 ...
- [Leetcode][JAVA] Recover Binary Search Tree (Morris Inorder Traversal)
Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...
- 二叉树的遍历(递归,迭代,Morris遍历)
二叉树的三种遍历方法: 先序,中序,后序,这三种遍历方式每一个都可以用递归,迭代,Morris三种形式实现,其中Morris效率最高,空间复杂度为O(1). 主要参考博客: 二叉树的遍历(递归,迭代, ...
- morris的用法
參數選項說明: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ...
- 二叉树的遍历(递归,迭代,Morris遍历)
二叉树的遍历: 先序,中序,后序: 二叉树的遍历有三种常见的方法, 最简单的实现就是递归调用, 另外就是飞递归的迭代调用, 最后还有O(1)空间的morris遍历: 二叉树的结构定义: struct ...
- 数据结构《13》----二叉树 Morris 前序遍历
三种二叉树的后序遍历的方法: 1. 递归 O(n) 时间复杂度, O(n) 空间复杂度 2. 迭代(用栈) O(n) 时间复杂度, O(n) 空间 ...
- 数据结构《10》----二叉树 Morris 中序遍历
无论是二叉树的中序遍历还是用 stack 模拟递归, 都需要 O(n)的空间复杂度. Morris 遍历是一种 常数空间 的遍历方法,其本质是 线索二叉树(Threaded Binary Tree), ...
- 时间作为横轴的图表(morris.js)超越昨天的自己系列(8)
超越昨天的自己系列(8) morris.js的官网有详细的例子:http://www.oesmith.co.uk/morris.js/ 特别注意它的依赖: <link rel="sty ...
随机推荐
- 玩转X-CTR100 l STM32F4 l FPU单精度浮点性能测试
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器如何开启ST ...
- python的条件判断
条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if age >= ...
- ubuntu 更改hostname, hosts后没有办法执行sudo 问题
由于主机名有重复的情况,所有需要更改主机名,遇到几个问题,主机名更改,重启系统以后不能执行sudo,另外也不知道root用户名密码.这个时候陷入了死循环. 网上搜集的办法,都是用sudo 命令去更改, ...
- C#中三层架构UI、BLL、DAL、Model实际操作
三层架构分为:表现层(UI).业务逻辑层(BLL).数据访问层(DAL)再加上实体类库(Model) 转载请注明出自朱朱家园https://blog.csdn.net/zhgl7688 1.实体类库( ...
- L312 难看懂的
There are few sadder sights than 8 pile of fan letters ,lovingly decorated with hand drawings,suffer ...
- 18-09-08 关于Linux 的安装遇到的一些小坑
具体参考我的有道笔记 备注 那个网络问题已经解决 先自动选择打上勾 然后在进行选择 并且正确输入 IP地址之类的 ====用utrallo 制作centos7.0 报错 以下是新的工具有效===== ...
- day 71-72 cookie 和session
拓展知识 request---->请求信息 属性: request.path # 获取访问文件路径 request.method属性 #获取请求中使用的HTTP方式(POST/G ...
- count函数详细介绍
select count(字段) from 表名; #得到字段中is not null的行数 select count(*)from 表名; #任何列,只要有一个非null就会被统计上.全为null( ...
- 使用scrapy ImagesPipeline爬取图片资源
这是一个使用scrapy的ImagesPipeline爬取下载图片的示例,生成的图片保存在爬虫的full文件夹里. scrapy startproject DoubanImgs cd DoubanIm ...
- Webservice客户端动态调用服务端功能方法
一.发布WebService服务 方式一:在服务端生成wsdl文件,下方客户端直接引用即可 优点:针对要发布的方法生成一个wsdl文件即可,无需多余配置. 缺点:每次服务端方法发生改变都需 ...