树2,用递归实现树的三种遍历

面试时提到的树,大部分是二叉树。每个结点最多只能有两个子结点。
在二叉树中,最重要的操作就是遍历,即按照某一顺序访问树中的所有结点。通常树有如下几种遍历方式:

前序遍历就是根节点在前面,中序遍历就是根节点在中间,后序遍历就是根节点在后面。

要很好地理解上面三种遍历方式,一定要深刻的理解这句话:我们能够把一个二叉树的任何子节点当成二叉树本身,一个子节点不单单只是一个节点,这是一个二叉树类实例,我们对一个节点进行操作,就是在对一个树进行操作。

理解这句话以后,就容易理解三种遍历是如何进行的了。
前序遍历访问一个节点,就是对这个节点为根的树,进行前序遍历。

如图2.5

一、三种遍历方法

1.1、前序遍历:

先访问根节点,再访问左子节点,最后访问右子节点
步骤1:
先访问以10为根节点的树,此时先访问根节点,于是会输出10。

步骤2:
再访问“大树”的左子节点6,一个节点就是一个树,访问左子节点6,就相当于用前序遍历访问左子树。于是对于左子树,先访问根节点6,于是会输出6。

步骤3:再访问左子树的左子节点4,此时是对以4为根节点的树,进行前序遍历。先访问根节点4,于是输出4。

步骤4:最左边的以4为根节点的树没有左右子节点,于是此树的前序遍历完毕。于是返回上一个树的前序遍历过程。上一个前序遍历已经访问了根节点6,左子节点4,于是接着访问右子节点8。而8是左子树的右子树,对这个树的根节点进行访问,于是会输出8。

步骤5:访问根节点8以后,发现没有左右子节点,于是返回上一个左子树的前序遍历,发现已经遍历完了 。于是再返回上一级“大树”的前序遍历。发现大树的前序遍历过程,该访问右子节点了。于是对右子节点14进行访问,也就相当于对右子树进行前序遍历访问,于是会先输出根节点14

步骤6:步骤就是再访问别的子节点,然后对子节点为根的树进行前序遍历。一直遍历完这个树。

到这里,我们会发现,对一个节点进行访问,那就是对以该节点为根节点的树进行访问,到底以后逐级返回就行。

1.2、中序遍历:

先访问左子节点,再访问根节点,再访问右子节点。
根节点在中间
步骤1:对大树进行访问,先访问左子节点6。
每个节点都是一个树.
对以6为根节点的左子树进行访问,先访问左子树的左子节点4.
对以4为根的树进行访问,发现左节点为空,访问完毕,于是再访问根节点4,输出4,再访问右子节点,发现为空。此时对以4为根的树访问完毕,返回上一级。
步骤2:此时左子树的左子节点4已经访问完毕,于是访问左子树的根节点,于是输出6.
...
步骤i:返回大树的根节点10以后,此时会对大树的右子节点14进行中序遍历访问。就是对右子树进行中序遍历访问。于是会先对右子树的左子节点12进行访问,访问完毕输出12以后,才会访问右子树的根节点14.
...

按照这个思想,中序遍历,从以10为根节点的树不断地访问下面的树,最终会返回
4,6,8,10,12,14,16

1.3、后序遍历:

先访问左子节点,再访问右子节点,最后 再访问根节点。
根节点在后面
按照上述逻辑,不断地递归访问,把每一个节点当成一个树,进行访问,然后再逐级返回。最终的输出结果就是4/8/6/12/16/14/10.

因为这 三种遍历都有递归和循环两种不同的实现方法。应该对这三种遍历的六种实现方法都了如指掌。

二、用代码实现这三种遍历

2.1、递归实现:

2.1.1、前序遍历

先用递归,递归比较简单:

  • 1、函数结束条件:传入的节点参数为空。
  • 2、按照前序遍历的顺序(对于传入的node,先访问以node为根节点的树的根节点,再访问此树的左子节点,再访问此树的右子节点)。
    于是应该先返回根节点
    然后把左子节点(即左子树)作为参数,传入函数中,让函数访问以左子节点为根节点的树。
    同样的把右子节点作为参数,传入函数中。
    代码实现:
def preorder(tree):
    if tree:
        print(tree.getRootVal())
        preorder(tree.getLeftChild())
        preorder(tree.getRightChild())

2.1.2、中序遍历

先访问左子节点==>先把左子节点(左子树)作为参数传入函数中
再访问根节点 ==> 返回根节点的值
再访问右子节点==>再把右子节点(右子树)作为参数传入函数中

代码实现:

def inorder(tree):
  if tree != None:
      inorder(tree.getLeftChild())
      print(tree.getRootVal())
      inorder(tree.getRightChild())

2.1.2、后序遍历

先访问左子节点==>先把左子节点(左子树)作为参数传入函数中
再访问右子节点==>再把右子节点(右子树)作为参数传入函数中
再访问根节点 ==> 返回根节点的值

代码实现:

def postorder(tree):
    if tree != None:
        postorder(tree.getLeftChild())
        postorder(tree.getRightChild())
        print(tree.getRootVal())
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容