之前刷leetcode的时候,知道求排列组合都需要深度优先搜索(DFS), 那么前序、中序、后序遍历是什么鬼,一直傻傻的分不清楚。直到后来才知道,原来它们只是DFS的三种不同策略。

N = Node(节点)

L = Left(左节点)

R = Right(右节点)

在深度优先搜索的时候,以Node的访问顺序,定义了三种不同的搜索策略:

前序遍历:结点 —> 左子树 —> 右子树

中序遍历:左子树—> 结点 —> 右子树

后序遍历:左子树 —> 右子树 —> 结点

##前序遍历

Pre-order: F, B, A, D, C, E, G, I, H.

##中序遍历

In-order: A, B, C, D, E, F, G, H, I.

在二叉搜索树(BST)中,中序遍历返回递增的一个序列

##后序遍历

Post-order: A, C, E, D, B, H, I, G, F.

##递归代码

递归实现比较直观容易,通常DFS遍历,都需要传递一个参数 or 设置一个全局变量,来保存结果

def pre_order(self, node, results):
if node is None:
return
results.append(node.val)
self.pre_order(node.left, results)
self.pre_order(node.right, results)
def in_order(self, node, results):
if node is None:
return
self.in_order(node.left, results)
results.append(node.val)
self.in_order(node.right, results)
def post_order(self, node, results):
if node is None:
return
self.post_order(node.left, results)
self.post_order(node.right, results)
results.append(node. 大专栏  树的三种DFS策略(前序、中序、后序)遍历val)

##非递归代码

深度优先遍历的非递归代码,一定用到的是stack数据接口

非递归实现前序和中序还可以,后续遍历就非常烧脑了

前序最简单,相当于for循环所有children,所以一版非递归DFS,就用前序就好了。

中序遍历,由于对于BST有一个递增的特性,所以还是比较常用的

def preorderTraversal(self, root):
results = []
if root is None:
return results
stack = [root]
while(len(stack) > 0):
node = stack.pop()
results.append(node.val)
# right first so left pop fisrt
if node.right is not None:
stack.append(node.right)
if node.left is not None:
stack.append(node.left)
return results
def inorderTraversal(self, root):
results = []
if root is None:
return results
stack = []
node = root
while(len(stack) > 0 or node is not None):
if (node is not None):
stack.append(node)
node = node.left
else:
node = stack.pop()
results.append(node.val)
node = node.right
return results
def postorderTraversal(self, root):
results = []
if root is None:
return results
node = root
stack = []
lastNodeVisted = None
while(len(stack) > 0 or node is not None):
if node is not None:
stack.append(node)
node = node.left
else:
peek = stack[-1] # last element
if (peek.right is not None and lastNodeVisted != peek.right):
node = peek.right
else:
results.append(peek.val)
lastNodeVisted = stack.pop()
return results

–END–

树的三种DFS策略(前序、中序、后序)遍历的更多相关文章

  1. java:数据结构(四)二叉查找树以及树的三种遍历

    @TOC 二叉树模型 二叉树是树的一种应用,一个节点可以有两个孩子:左孩子,右孩子,并且除了根节点以外每个节点都有一个父节点.当然这种简单的二叉树不能解决让树保持平衡状态,例如你一直往树的左边添加元素 ...

  2. 三种java 去掉字符串中的重复字符函数

    三种java 去掉字符串中的重复字符函数 public static void main(string[] args) { system.out.println(removerepeatedchar( ...

  3. 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序

    接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...

  4. 前序+中序->后序 中序+后序->前序

    前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...

  5. SDUT-2804_数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 已知一颗二叉树的中序 ...

  6. 二叉树 遍历 先序 中序 后序 深度 广度 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. SDUT OJ 数据结构实验之二叉树八:(中序后序)求二叉树的深度

    数据结构实验之二叉树八:(中序后序)求二叉树的深度 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Probl ...

  8. 给出 中序&后序 序列 建树;给出 先序&中序 序列 建树

    已知 中序&后序  建立二叉树: SDUT 1489 Description  已知一棵二叉树的中序遍历和后序遍历,求二叉树的先序遍历 Input  输入数据有多组,第一行是一个整数t (t& ...

  9. 【C&数据结构】---关于链表结构的前序插入和后序插入

    刷LeetCode题目,需要用到链表的知识,忽然发现自己对于链表的插入已经忘得差不多了,以前总觉得理解了记住了,但是发现真的好记性不如烂笔头,每一次得学习没有总结输出,基本等于没有学习.连复盘得机会都 ...

随机推荐

  1. ⼩程序中⽀持es7的async语法

    ⼩程序中⽀持es7的async语法 es7的 async 号称是解决回调的最终⽅案 在⼩程序的开发⼯具中,勾选 es6转es5语法 下载 facebook 的 regenerator 库中的 rege ...

  2. java 计算函数运行时间

    long start,end; start = System.currentTimeMillis(); for (int i = 0; i < 2000000000; i++) {} end = ...

  3. 一、Cookie和Session介绍

    会话跟踪 1. 什么是会话  * 用户拨打10086,从服务台接通后会话开始:  * 用户发出话费查询请求,服务台响应.这是该会话中的一个请求:  * 用户发出套餐变更请求,服务台响应.这是该会话中的 ...

  4. 吴裕雄--天生自然 JAVA开发学习:数据结构

    import java.util.Vector; import java.util.Enumeration; public class EnumerationTester { public stati ...

  5. 获取cell上按钮事件

    原由:点击cell上的按钮,无法获取button对应的cell位置 //获取按钮上层控件,也就是cell本身 AccountCell *cell= (AccountCell *)[按钮名称 super ...

  6. 二十七、rsync同步工具

    1.什么是rsync? Rsync是一款开源的.快速的,多功能的,可实现全量及增量的本地或者远程数据同步备份的优秀工具.windows和linux都可以. 官网:http:www.samba.org/ ...

  7. TCP、UDP、HTTP与HTTPS

    TCP.UDP.HTTP与HTTPS都是通信协议,在这里首先先介绍一下什么是通信协议. 什么是通信协议? 通信协议(communications protocol)是指双方实体完成通信或服务所必须遵循 ...

  8. signal之——异步回收机制2

    前言:上一篇的处理方法可以解决所有回收问题,但是如果我们不考虑子进程的返回状态,那么可以使内核来进行对子进程的回收 代码如下: //如果无需关心进程结束状态 可以设置子进程结束时不产生僵尸进程有内核值 ...

  9. iOS路由详解

    本文如题,路由详解,注定是一篇详细解释iOS路由原理及使用的文章,由于此时正在外地出差,无法详细一一写出,只能不定时的补充. 一.什么是iOS路由 路由一词来源于路由器,可以实现层级之间消息转发的功能 ...

  10. Grails Controller - respond 方法

    基本用法 官方文档:http://docs.grails.org/latest/ref/Controllers/respond.html 为当前 respond 语句所在 action 所对应的页面返 ...