Morris遍历求解二叉树前中后序遍历
来源:互联网 发布:天盾苹果手机数据恢复软件 编辑:程序博客网 时间:2024/06/05 03:12
前面博文中曾讲过用递归和递推的方法遍历,这两种方法因为要用到栈来记录,所以时间复杂度O(n),空间复杂度O(n)
Morris遍历利用了叶节点的悬空指针帮助遍历,模仿递归遍历三次访问节点过程,但是他只能做到若节点有左孩子,实现两次访问,若无左孩子,实现一次访问。所以在后续遍历时,要利用翻转链表的方法对右子树逆序打印。
Morris遍历思想:
1、若节点node无左子树,node向右指针方向移动
2、若节点node有左子树,查看左子树上最右的节点,若此节点右指针为空,使得右指针指向node,node向它左指针方向移动
若此节点右指针指向node,使得右指针指向空,node向它右指针方向移动
JAVA程序:
package problems_2017_08_21;
public class Problem_01_MorrisTraversal {
public static class Node {
public int value;
Node left;
Node right;
public Node(int data) {
this.value = data;
}
}
public static void morrisPre(Node head) {
if (head == null) {
return;
}
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;
}
if (cur2.right == null) {
cur2.right = cur1;
System.out.print(cur1.value + " ");
cur1 = cur1.left;
continue;
} else {
cur2.right = null;
}
} else {
System.out.print(cur1.value + " ");
}
cur1 = cur1.right;
}
System.out.println();
}
public static void morrisIn(Node head) {
if (head == null) {
return;
}
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;
}
if (cur2.right == null) {
cur2.right = cur1;
cur1 = cur1.left;
continue;
} else {
cur2.right = null;
}
}
System.out.print(cur1.value + " ");
cur1 = cur1.right;
}
System.out.println();
}
public static void morrisPos(Node head) {
if (head == null) {
return;
}
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;
}
if (cur2.right == null) {
cur2.right = cur1;
cur1 = cur1.left;
continue;
} else {
cur2.right = null;
printEdge(cur1.left);
}
}
cur1 = cur1.right;
}
printEdge(head);
System.out.println();
}
public static void printEdge(Node head) {
Node tail = reverseEdge(head);
Node cur = tail;
while (cur != null) {
System.out.print(cur.value + " ");
cur = cur.right;
}
reverseEdge(tail);
}
public static Node reverseEdge(Node from) {
Node pre = null;
Node next = null;
while (from != null) {
next = from.right;
from.right = pre;
pre = from;
from = next;
}
return pre;
}
// for test -- print tree
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}
public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}
public static void main(String[] args) {
Node head = new Node(4);
head.left = new Node(2);
head.right = new Node(6);
head.left.left = new Node(1);
head.left.right = new Node(3);
head.right.left = new Node(5);
head.right.right = new Node(7);
printTree(head);
morrisPre(head);
morrisIn(head);
morrisPos(head);
printTree(head);
}
}
C++程序:
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
int val;
node *left;
node *right;
node():val(0),left(NULL),right(NULL){}
};
//前序
void morrispre(node *head)
{
if(head==NULL)
return;
node *curr=head;
node *p;
while(curr!=NULL)
{
p=curr->left;
if(p!=NULL)
{
while(p->right!=NULL&&p->right!=curr)
p=p->right;
if(p->right==NULL)
{
p->right=curr;
cout<<curr->val;
curr=curr->left;
continue;
}
if(p->right==curr)
{
p->right=NULL;
}
}
else
cout<<curr->val;
curr=curr->right;
}
}
//中序
void morrismid(node *head)
{
if(head==NULL)
return;
node *curr=head;
node *p;
while(curr!=NULL)
{
p=curr->left;
if(p!=NULL)
{
while(p->right!=NULL&&p->right!=curr)
p=p->right;
if(p->right==NULL)
{
p->right=curr;
curr=curr->left;
continue;
}
if(p->right==curr)
{
p->right=NULL;
}
}
cout<<curr->val;
curr=curr->right;
}
}
//后序
node* reversr(node *head);
void printnode(node *head);
void morrispos(node *head)
{
if(head==NULL)
return;
node *curr=head;
node *p;
while(curr!=NULL)
{
p=curr->left;
if(p!=NULL)
{
while(p->right!=NULL&&p->right!=curr)
p=p->right;
if(p->right==NULL)
{
p->right=curr;
curr=curr->left;
continue;
}
if(p->right==curr)
{
p->right=NULL;
printnode(curr->left);
}
}
curr=curr->right;
}
printnode(head);
}
node* reversr(node *head)
{
node *next=NULL;
node *pre=NULL;
while(head!=NULL)
{
next=head->right;
head->right=pre;
pre=head;
head=next;
}
return pre;
}
void printnode(node *head)
{
node *tail=reversr(head);
node *curr=tail;
while(curr!=NULL)
{
cout<<curr->val;
curr=curr->right;
}
reversr(tail);
}
int main()
{
node *head=new node();
head->val=1;
head->left=new node();
head->left->val=2;
head->right=new node();
head->right->val=3;
head->left->left=new node();
head->left->left->val=4;
head->left->right=new node();
head->left->right->val=5;
head->right->left=new node();
head->right->left->val=6;
head->right->right=new node();
head->right->right->val=7;
morrispre(head);
cout<<endl;
morrismid(head);
cout<<endl;
morrispos(head);
system("pause");
return 0;
}
- Morris遍历求解二叉树前中后序遍历
- Morris遍历二叉树
- Morris 二叉树遍历
- Morris遍历二叉树
- morris 遍历二叉树
- Morris二叉树遍历算法
- Morris遍历二叉树算法
- Morris Traversal 遍历二叉树
- Morris二叉树遍历算法
- Morris二叉树遍历算法
- Morris二叉树遍历算法
- Morris二叉树遍历算法
- Morris方法遍历二叉树
- Morris方法遍历二叉树
- Morris二叉树遍历算法
- Morris算法遍历二叉树
- Morris二叉树遍历算法
- Morris二叉树遍历算法
- HDU
- 文章标题
- POJ
- hdu 4749 Parade Show (暴力水 (正解应该是kmp变形))
- OPENCV编译Videoio模块问题解决
- Morris遍历求解二叉树前中后序遍历
- ExoPlayer Talk 01 缓存策略分析与优化
- memcache、redis原理对比
- 深度学习网络调参技巧_02
- 在Qt 5.9.1通过qt.conf指定共享库路径部署应用程序
- map函数,key相同的value存在list里,对dic进行排序
- 【leetcode】第46题 Permutations(递归法)题目+解析+代码
- 算法竞赛入门经典 下落的树叶
- 三个关于字符串的考点