《程序员代码面试指南》第三章 二叉树问题 遍历二叉树的神级方法 morris
题目
遍历二叉树的神级方法 morris
java代码
package com.lizhouwei.chapter3;
/**
* @Description:遍历二叉树的神级方法 morris
* @Author: lizhouwei
* @CreateDate: 2018/4/14 17:15
* @Modify by:
* @ModifyDate:
*/
public class Chapter3_5 {
//morris中序
public void morrisInOrder(Node head) {
Node cur1 = head;
Node cur2 = null;//左子节点
while (cur1 != null) {
cur2 = cur1.left;//当前节点的左子节点
if (cur2 != null) {
//循环遍历到左子节点的最右子节点
while (cur2.right != null && cur2.right != cur1) {
cur2 = cur2.right;
}
//如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
if (cur2.right == null) {
cur2.right = cur1;
cur1 = cur1.left;
continue;
} else {
//如过最右节点已指向cur1,恢复,则使之指向null,
cur2.right = null;
}
}
//如果cur1.left 为null,则说明没有左子树,则开始打印父节点;
System.out.print(cur1.value + " ");
cur1 = cur1.right;
}
System.out.println();
}
//morris前序
public void morrisPreOrder(Node head) {
Node cur1 = head;
Node cur2 = null;//左子节点
while (cur1 != null) {
cur2 = cur1.left;//当前节点的左子节点
if (cur2 != null) {
//循环遍历到左子节点的最右子节点
while (cur2.right != null && cur2.right != cur1) {
cur2 = cur2.right;
}
//如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
if (cur2.right == null) {
cur2.right = cur1;
System.out.print(cur1.value + " ");//遇见父节点,先打印父节点
cur1 = cur1.left;
continue;
} else {
//如过最右节点已指向cur1,恢复,则使之指向null,
cur2.right = null;
}
} else {
//如果cur1.left 为null,说明没有左子节点,在切换到右子树之前先打印父节点
System.out.print(cur1.value + " ");
}
cur1 = cur1.right;
}
System.out.println();
}
//morris后序
public void morrisPostOrder(Node head) {
Node cur1 = head;
Node cur2 = null;//左子节点
while (cur1 != null) {
cur2 = cur1.left;//当前节点的左子节点
if (cur2 != null) {
//循环遍历到左子节点的最右子节点
while (cur2.right != null && cur2.right != cur1) {
cur2 = cur2.right;
}
//如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
if (cur2.right == null) {
cur2.right = cur1;
cur1 = cur1.left;
continue;
} else {
//如过最右节点已指向cur1,恢复,则使之指向null,
cur2.right = null;
printEdge(cur1.left);
}
}
cur1 = cur1.right;
}
printEdge(head);
System.out.println();
}
//打印节点
public void printEdge(Node head) {
Node tail = reverse(head);
Node cur = tail;
while (cur != null) {
System.out.print(cur.value + " ");
cur = cur.right;
}
//恢复链表
reverse(tail);
}
//反转节点的右子节点链
public Node reverse(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.right;
head.right = pre;
pre = head;
head = next;
}
return pre;
}
//测试
public static void main(String[] args) {
Chapter3_5 chapter = new Chapter3_5();
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Node head = NodeUtil.generTree(arr, 0, arr.length - 1);
System.out.print("morris中序遍历:");
chapter.morrisInOrder(head);
System.out.print("非递归中序遍历:");
NodeUtil.inOrder(head);
System.out.println();
System.out.print("morris前序遍历:");
chapter.morrisPreOrder(head);
System.out.print("非递归前序遍历:");
NodeUtil.preOrder(head);
System.out.print("morris后序遍历:");
chapter.morrisPostOrder(head);
System.out.print("非递归后序遍历:");
NodeUtil.postOrder(head);
}
}
《程序员代码面试指南》第三章 二叉树问题 遍历二叉树的神级方法 morris的更多相关文章
- 《程序员代码面试指南》第一章 栈和队列 最大值减去最小值小于或等于num的数量
题目 给定整数数组arr和整数num,共返回多少的数组满足如下情况 max(arr[i...j]) - min(arr[i...j]) <= num max(arr[i...j])表示数组arr ...
- 《程序员代码面试指南》第一章 栈和队列 构造数组的MaxTree
题目 给出一个无重复元素的数组,构造此数组的MaxTree, java代码 /** * @Description: 构造数组的MaxTree * @Author: lizhouwei * @Creat ...
- 《程序员代码面试指南》第一章 栈和队列 设计一个有getMin功能的栈
题目 实现一个特殊的栈,在实现栈的基本功能上,再实现返回栈中最小的元素的操作 要求 1. pop.push.getMin操作时间复杂度都是O(1) 2. 设计的栈类型可以使用现成的栈结构 java代码 ...
- 《程序员代码面试指南》第二章 链表问题 将单链表每K个节点之间逆序
样例 链表1-2-3-4-5-6-7-8-9-10 K=3 ,结果 3-2-1-6-5-4-9-8-7-10 java代码 /** * @Description:将单链表每K个节点之间逆序 * @Au ...
- 《程序员代码面试指南》第二章 链表问题 删除中间节点和a/b处节点
题目 例如 1-2-3-4 删除2,1-2-3-4-5 删除3 例如 a=1,b =2 java代码 /** * @Description:删除中间节点和a/b处节点 * @Author: lizho ...
- 《程序员代码面试指南》第二章 链表问题 在单链表和双链表中删除倒数第K个节点
题目 在单链表和双链表中删除倒数第K个节点 java代码 /** * @Description:在单链表和双链表中删除倒数第K个节点 * @Author: lizhouwei * @CreateDat ...
- [程序员代码面试指南]第9章-在两个长度相等的排序数组中找到第k小的数(二分)
题目 给定两个有序数组arr1和arr2,再给定一个整数k,返回所有的数中第k小的数. 题解 利用题目"在两个长度相等的排序数组中找到第上中位数"的函数 分类讨论 k < 1 ...
- 程序员代码面试指南 IT名企算法与数据结构题目最优解
原文链接 这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮 ...
- 程序员代码面试指南:IT名企算法与数据结构题目最优解
第1章栈和队列 1设计一个有getMin功能的栈(士★☆☆☆) 1由两个栈组成的队列(尉★★☆☆) 5如何仅用递归函数和栈操作逆序一个栈(尉★★☆☆) 8猫狗队列(士★☆☆☆)10用一个栈实现另一 ...
随机推荐
- oracle字符串处理函数
1.LOWER(string) 将输入的字符串转换成小写: 2.UPPER(string) 将输入的字符串转换成大写: 3.INITCAP(string) 将输入的字符串单词的首字母转换成大写(如果不 ...
- nginx proxy cache配置和清理
1.nginx需要编译Purge模块 2.nginx.conf 配置cache: proxy_cache_path /home/cache/xxx levels=1:2 keys_zone=cac ...
- Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结
Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结 1.1. Java的编年史2 ...
- synchronized 锁优化
synchronized 在jdk 1.7之前是重量级锁,独占锁,非公平锁.jdk1.7之后,synchronized引入了 偏向锁,自旋锁,轻量级锁,重量级锁 自旋锁 当线程在获取锁的时候,如果发现 ...
- [译]GLUT教程 - 整合代码7
Lighthouse3d.com >> GLUT Tutorial >> Extras >> The Code So Far VII 以下是子窗体的最终版本代码. ...
- JDK自带的定时任务
import java.util.TimerTask; /** * 实现定时任务 * */ public class MyTimerTask extends TimerTask { @Override ...
- Arbitrage - poj 2240 (Bellman-ford)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17374 Accepted: 7312 Description Ar ...
- linux vmware提示:此虚拟机似乎正在使用中,取得该虚拟机的所有权失败错误
用vm的时候,没有挂起和关闭虚拟机,直接关实体机.然后不幸的就异常了. 然后今天用的时候提示 此虚拟机似乎正在使用中. 如果此虚拟机已在使用中,请按“取消”按钮,以免损坏它.如果此虚拟机未使用,请按“ ...
- 推荐一个android 日期时间选择器(转)
最近接触了日期选择的功能,那么肯定得需要一个日期选择控件,Android 系统有自带的 DatePicker 控件,但是不说这个控件有多 难看吧,现在 Android 手机版本那么多,用户弹出来的控件 ...
- 什么是Java Server Pages?
JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结束. JSP是一种Java servlet ...