[LeetCode] Binary Tree Preorder/Inorder/Postorder Traversal
前中后遍历 递归版
/* Recursive solution */
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) { vector<int> result;
preorderTraversal(root, result); return result;
} void preorderTraversal(TreeNode *root, vector<int>& result)
{
if(root == NULL) return;
result.push_back(root->val); preorderTraversal(root->left, result);
preorderTraversal(root->right, result);
} };
/* Recursive solution */
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) { vector<int> result;
inorderTraversal(root, result); return result;
} void inorderTraversal(TreeNode *root, vector<int>& result)
{
if(root == NULL) return; inorderTraversal(root->left, result);
result.push_back(root->val);
inorderTraversal(root->right, result);
} };
/* Recursive solution */
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) { vector<int> result;
postorderTraversal(root, result); return result;
} void postorderTraversal(TreeNode *root, vector<int>& result)
{
if(root == NULL) return; postorderTraversal(root->left, result);
result.push_back(root->val);
postorderTraversal(root->right, result);
} };
下面是迭代版本
1 preorder: 节点入栈一次, 入栈之前访问。
2 inorder:节点入栈一次,出栈之后访问。
3 postorder:节点入栈2次,第二次出战后访问。
 class Solution {
 public:
     vector<int> preorderTraversal(TreeNode *root) {
         vector<int> result;
         stack<TreeNode*> stack;
         TreeNode *p = root;
         while( NULL != p || !stack.empty())
         {
             while(NULL != p)
             {
                 result.push_back(p->val);
                 stack.push(p);
                 p = p->left;
             }
             if(!stack.empty())
             {
                 p= stack.top();
                 stack.pop();
                 p=p->right;
             }
         }
         return result;
     }
 };
 class Solution {
 public:
     vector<int> inorderTraversal(TreeNode *root) {
         vector<int> result;
         stack<TreeNode*> stack;
         TreeNode *p = root;
         while( NULL != p || !stack.empty())
         {
             while(NULL != p)
             {
                 stack.push(p);
                 p = p->left;
             }
             if(!stack.empty())
             {
                 p= stack.top();
                 stack.pop();
                 result.push_back(p->val);
                 p=p->right;
             }
         }
         return result;
     }
 };
后续, 用bStack标记是否是第一次访问,如果是第一次访问,再次入栈,否则直接访问,记得将P = NULL;
 class Solution {
 public:
     vector<int> postorderTraversal(TreeNode *root) {
         vector<int> result;
         stack<TreeNode*> stack;
         std::stack<bool> bStack;
         TreeNode *p = root;
         bool isFirst;
         while( NULL != p || !stack.empty())
         {
             while(NULL != p)
             {
                 stack.push(p);
                 bStack.push(false);
                 p = p->left;
             }
             if(!stack.empty())
             {
                 p= stack.top();
                 stack.pop();
                 isFirst = bStack.top();
                 bStack.pop();
                 if(isFirst == )
                 {
                     stack.push(p);
                     bStack.push(true);
                     p=p->right;
                 }
                 else
                 {
                     result.push_back(p->val);
                     p = NULL;
                 }
             }
         }
         return result;
     }
 };
另外一种前序迭代实现
 class Solution {
     public:
         vector<int> preorderTraversal(TreeNode *root) {
             vector<int> result;
             const TreeNode *p;
             stack<const TreeNode *> s;
             p = root;
             if (p != nullptr) s.push(p);
             while (!s.empty()) {
                 p = s.top();
                 s.pop();
                 result.push_back(p->val);
                 if (p->right != nullptr) s.push(p->right);
                 if (p->left != nullptr) s.push(p->left);
             }
             return result;
         }
 };
Morris 遍历
morris分为3个步骤,建立link,访问最左节点,删除link,morris前序和中序遍历只要调整在那里visit节点即可,框架相同。。
可以参考:http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html
Morris算法与递归和使用栈空间遍历的思想不同,它使用二叉树中的叶节点的right指针来保存后面将要访问的节点的信息,当这个right指针使用完成之后,再将它置为NULL,但是在访问过程中有些节点会访问两次,所以与递归的空间换时间的思路不同,Morris则是使用时间换空间的思想,先来看看Morris中序遍历二叉树的算法实现:
1 Morris 中序遍历
class Solution {
    public:
        void morris_inorder(TreeNode* T) {
            TreeNode *p, *temp;
            p = T;
            while(p) {
                if(p->left == NULL) {
                    printf("%4d \n", p->val);
                    p = p->right;
                } else {
                    temp = p->left;
                    // find the most right node of the p's left node
                    while(temp->right != NULL && temp->right != p) {
                        temp = temp->right;
                    }
                    if(temp->right == NULL) {
                        temp->right = p;
                        p = p->left;
                    } else {
                        printf("%4d \n", p->val);
                        temp->right = NULL;
                        p = p->right;
                    }
                }
            }
        }
};
同时, 以 下面的二叉树为例,走一遍流程:
4
/ \
2 7
/ \ / \
1 3 5 8
p指向4, temp指向2,然后while Loop,tmp指向3, 3->right = 4, p = p->left=2; 建立链接
p指向2, tmp指向1, 然后while Loop,tmp指向1, 1->right = 2, p = p->left = 1;建立链接
p指向1, 由于p->left == NULL,visit(1), p = p ->right = 2,
p指向2, tmp指向1, 然后while Loop,tmp指向1, visit(2), 1->right = NULL, p = p->right = 3;断开链接
p指向3, 由于p->left == NULL,visit(3), p = p ->right = 4,
p指向4, tmp指向2, 然后while Loop,tmp指向3, visit(4), 3->right = NULL, p = p->right = 7;断开链接
p指向7, tmp指向5, 然后while Loop,tmp指向5, 5->right = 7, p = p->left = 5;建立链接
p指向5, 由于p->left == NULL,visit(5), p = p ->right = 7,
p指向7, tmp指向5, 然后while Loop,tmp指向5, visit(7), 5->right = NULL, p = p->right = 8;断开链接
p指向8, 由于p->left == NULL,visit(3), p = p ->right = NULL,
退出循环
加上些打印信息,更好理解
class Solution {
    public:
        void morris_inorder(TreeNode* T) {
            TreeNode *p, *temp;
            p = T;
            while(p) {
                if(p->left == NULL) {
                    printf("visit %4d \n", p->val);
                    p = p->right;
                } else {
                    temp = p->left;
                    // find the most right node of the p's left node
                    while(temp->right != NULL && temp->right != p) {
                        temp = temp->right;
                    }
                    if(temp->right == NULL) {
                        cout << "build link for " << temp->val <<"-->" << p->val << endl;
                        temp->right = p;
                        p = p->left;
                    } else {
                        printf("visit %4d \n", p->val);
                        cout << "destory link for " << temp->val <<"-->" << p->val << endl;
                        temp->right = NULL;
                        p = p->right;
                    }
                }
            }
        }
};
build link for -->
build link for -->
visit
visit
destory link for -->
visit
visit
destory link for -->
build link for -->
visit
visit
destory link for -->
visit     
morris 前序遍历
        void morris_preorder(TreeNode* T) {
            TreeNode *p, *temp;
            p = T;
            while(p) {
                if(p->left == NULL) {//visit the leftmost leaf node
                    printf("visit %4d \n", p->val);
                    p = p->right;
                } else {
                    temp = p->left;
                    // find the most right node of the p's left node
                    while(temp->right != NULL && temp->right != p) {
                        temp = temp->right;
                    }
                    if(temp->right == NULL) {//build the link
                        printf("visit %4d \n", p->val);
                        temp->right = p;
                        p = p->left;
                    } else {//remove the link
                        temp->right = NULL;
                        p = p->right;
                    }
                }
            }
        }
3 morris 后序遍历
这里的reverse 和reverse单链表意思相同,另外之所以使用链表的reverse,而没有采用辅助stack后者vector是考虑要求空间复杂度O(1)的考虑
void reverse(TreeNode *from, TreeNode *to) // reverse the tree nodes 'from' -> 'to'.
{
if (from == to)
return;
TreeNode *x = from, *y = from->right, *z;
while (true)
{
z = y->right;
y->right = x;
x = y;
y = z;
if (x == to)
break;
}
} void printReverse(TreeNode* from, TreeNode *to) // print the reversed tree nodes 'from' -> 'to'.
{
reverse(from, to); TreeNode *p = to;
while (true)
{
printf("%d ", p->val);
if (p == from)
break;
p = p->right;
} reverse(to, from);
} void postorderMorrisTraversal(TreeNode *root) {
TreeNode dump();
dump.left = root;
TreeNode *cur = &dump, *prev = NULL;
while (cur)
{
if (cur->left == NULL)
{
cur = cur->right;
}
else
{
prev = cur->left;
while (prev->right != NULL && prev->right != cur)
prev = prev->right; if (prev->right == NULL)
{
prev->right = cur;
cur = cur->left;
}
else
{
printReverse(cur->left, prev); // call print
prev->right = NULL;
cur = cur->right;
}
}
}
}
还是以上述bst为例,走一遍code:
p指向dummy, temp指向4,然后while Loop,tmp指向8, 8->right = dummy, p = p->left=4; 建立链接
p指向4, temp指向2,然后while Loop,tmp指向3, 3->right = 4, p = p->left=2; 建立链接
p指向2, tmp指向1, 然后while Loop,tmp指向1, 1->right = 2, p = p->left = 1;建立链接
p指向1, 由于p->left == NULL, p = p ->right = 2,
p指向2, tmp指向1, 然后while Loop,tmp指向1, reversePrint(1,1), 1->right = NULL, p = p->right = 3;断开链接
p指向3, 由于p->left == NULL, p = p ->right = 4,
p指向4, tmp指向2, 然后while Loop,tmp指向3, reversePrint(2,3), 3->right = NULL, p = p->right = 7;断开链接
p指向7, tmp指向5, 然后while Loop,tmp指向5, 5->right = 7, p = p->left = 5;建立链接
p指向5, 由于p->left == NULL, p = p ->right = 7,
p指向7, tmp指向5, 然后while Loop,tmp指向5, reversePrint(5,5), 5->right = NULL, p = p->right = 8;断开链接
p指向8, 由于p->left == NULL,, p = p ->right = dummy,
p指向dummy, tmp指向4, 然后while Loop,tmp指向8, reversePrint(4,8), 8->right = NULL, p = p->right = null;断开链接
退出循环
[LeetCode] Binary Tree Preorder/Inorder/Postorder Traversal的更多相关文章
- LeetCode之“树”:Binary Tree Preorder &&  Inorder && Postorder Traversal
		Binary Tree Preorder Traversal 题目链接 题目要求: Given a binary tree, return the preorder traversal of its ... 
- LC 144. / 94. / 145. Binary Tree Preorder/ Inorder/ PostOrder Traversal
		题目描述 144. Binary Tree Preorder Traversal 94. Binary Tree Inorder Traversal 145. Binary Tree Postorde ... 
- 【题解】【BT】【Leetcode】Binary Tree Preorder/Inorder/Postorder   (Iterative Solution)
		[Inorder Traversal] Given a binary tree, return the inorder traversal of its nodes' values. For exam ... 
- LeetCode: Binary Tree Preorder Traversal  解题报告
		Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' valu ... 
- [LeetCode] Binary Tree Preorder Traversal 二叉树的先序遍历
		Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tr ... 
- [LeetCode] Binary Tree Preorder Traversal
		Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tr ... 
- [leetcode]Binary Tree Preorder Traversal @ Python
		原题地址:http://oj.leetcode.com/problems/binary-tree-preorder-traversal/ 题意:这题用递归比较简单.应该考察的是使用非递归实现二叉树的先 ... 
- LeetCode——Binary Tree Preorder Traversal
		Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary t ... 
- LeetCode Binary Tree Preorder Traversal  先根遍历
		题意:给一棵树,求其先根遍历的结果. 思路: (1)深搜法: /** * Definition for a binary tree node. * struct TreeNode { * int va ... 
随机推荐
- PHP基础12:数组
			<?php //1.实例 $array = array("VOLVO","BMW","SASS"); for ($i=0; $i &l ... 
- nginx缓存模块配置总结proxy_cache(未完)
			简介:此缓存设置用到了第三方模块purge,使用的时候就在源链接和访问的具体内容之间加入关键字"/purge/"即可. 如:访问http://192.168.0.1/a.png 会 ... 
- Caffe学习系列(5):其它常用层及参数
			本文讲解一些其它的常用层,包括:softmax_loss层,Inner Product层,accuracy层,reshape层和dropout层及其它们的参数配置. 1.softmax-loss so ... 
- [CareerCup] 11.7 Tower of People in Circus 马戏团的人塔
			11.7 A circus is designing a tower routine consisting of people standing atop one another's shoulder ... 
- [MetaHook] Load large texture from model
			We need hook "GL_LoadTexture" engine function. GL_LOADTEXTURE_SIG from hw.dll(3266) engine ... 
- 《图解tcp/ip》读书笔记(一)
			我先讲三句话: 一."万物互联的时代到了."我们生活在这样一个互联网急速发展的时代,也许很快就会发现,你能接触到的一切都可以连接到互联网了,电脑.手机这 ... 
- 20145311利用gdb调试汇编代码
			利用GDB调试汇编代码 首先编写c语言原代码,我使用的是同学分析过的代码 #include<stdio.h>short addend1 = 1;static int addend2 = 2 ... 
- 编写高质量iOS代码与OS X代码的effective 方法小结
			一.熟悉OC: 了解OC的起源: OC和C++,Java等面向对象语言类似,不过有很方面差别.因为该语言使用 消息结构而非函数调用. 消息结构和函数调用的区别:前者是在其运行时所应执行的代码由运行环 ... 
- iOS端给unity发送消息,实现两者交互。
			上一篇我们简单说了一下unity发消息给iOS端.现在我们就来说一下iOS端给unity发送消息的简单使用. 首先iOS端做得事情其实很简单就一句话,直接上代码 /** * 第一个参数:是unity那 ... 
- 谏牲口TT十思疏
			予闻:求木之长着,必固其根本:欲流之远者,必浚其泉源:思吾之长者,必积其学识.源不深而望流之远,根不固而求木之长,识不积而思指日之安,斯虽下愚,知其不可,而况于TT乎?TT当举家之重,虑只此一生,将孝 ... 
