写给媳妇儿的算法(十五)——二叉树及其遍历

二叉树 是一种特殊的“树”结构,它每个节点最多有两个子树。

是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。树跟图的区别就在于,树是有 层次结构 的。

树与图.png

树中只有子节点,没有父节点的节点是 根节点;既有父节点,又有子节点的节点是普通的节点;只有父节点,没有子节点的节点,是 叶子节点

二叉树

二叉树 就是每个节点最多有两个子树(子节点)的树:

二叉树、满二叉树、完全二叉树.png

满二叉树: 叶子节点全部都在最底层,除了叶子节点,每个节点都有左右两个子节点的二叉树。
完全二叉树:叶子节点只有最下面两层,最下层叶子节点全都靠左排列,除了最后一层的叶子节点意外其他任何一层的节点都是满的,这样的二叉树。

二叉树存储方式

二叉树可以使用链表来实现,也可以使用数组来实现,这两种存储方式各有各的优缺点。

链式存储

链式存储的二叉树.png

二叉树使用链式存储,每一个节点都需要包含三部分的内容:本节点的值、左子节点指针、右子节点指针。这种方式只要知道父节点,就能依次找到该节点的子节点。这种链式存储的方式每个节点需要包含这三部分,所以会浪费一定的存储空间,但是实现起来很容易,对于内存空间的使用比较灵活。

顺序存储

使用数组进行顺序存储.png

二叉树使用顺序存储,需要使用一个数组。由于数组是一个连续的存储空间,所以,数组的下标是连续的,且可以计算出来的。这样就免去了链式存储中每个节点都需要记录子节点指针的空间,每个节点只需要记录自己的值就可以了。

从图中的值可以看出来,假设父节点的存储位置设为i,那么,左子节点位置 = 2 × i;右子节点位置 = 2 × i + 1。这样我们就可以通过下标计算来计算出来各个节点的位置了。

另外,如图,如果二叉树不是完全二叉树的话,那么图中的G点(怪怪的感觉😂)就不存在,那么右边的存储数组的第6个位置就会不存储任何东西,这样的话,造成了数组存储的离散,导致空间浪费。如果这样的情况多了,空间就会浪费的多的多。所以如果最后一排叶子节点都靠左排列,即二叉树为完全二叉树的时候,空间才会是最省的,所以完全二叉树的概念并不是没有用的。

二叉树遍历

要想从头到尾将二叉树遍历完全,可以有很多种方式。先、中、后序遍历(深度优先);层次遍历(广度优先)……层次遍历的话可以采用一个队列来实现,这个在广度优先算法一篇写过了。深度优先的话,可以有三种遍历的方式:先序遍历、中序遍历、后序遍历。


二叉树三种遍历方式.png

这三种遍历方式就是跟节点的区别在于对于每个节点的访问逻辑顺序不同,都是利用递归(非递归先不考虑)来进行访问:

先序遍历:①打印父节点 => ②访问父节点的左子节点 => ③访问父节点的右子节点
中序遍历:①访问父节点的左子节点 => ②打印父节点 => ③访问父节点的右子节点
后序遍历:①访问父节点的左子节点 => ②访问父节点的右子节点 => ③打印父节点

所谓的前中后,指的是打印父节点值的时机。先序遍历是先打印父节点,然后递归访问父节点的左子节点,然后再递归访问父节点的右子节点……

算法实现

# -*- coding: utf-8 -*-
# @Time    : 2019-03-25 16:41
# @Author  : Jaedong
# @Version : 3.6
# @File    : TraversingBinaryTree.py
# @Software: PyCharm


class Node:
    value = ''
    leftNode = None
    rightNode = None

    def __init__(self, value, leftNode, rightNode):
        self.value = value
        self.leftNode = leftNode
        self.rightNode = rightNode

# 先序遍历就是:根节点->左子树->右子树
def preorder_traversal(root):
    if root == None:
        return

    print(root.value)
    preorder_traversal(root.leftNode)
    preorder_traversal(root.rightNode)

# 中序遍历就是:左子树->根节点->右子树
def inorder_traversal(root):
    if root == None:
        return

    inorder_traversal(root.leftNode)
    print(root.value)
    inorder_traversal(root.rightNode)

# 后序遍历就是:左子树->右子树->根节点
def postorder_traversal(root):
    if root == None:
        return

    postorder_traversal(root.leftNode)
    postorder_traversal(root.rightNode)
    print(root.value)


# 简单粗暴,先来一棵二叉树
node_d = Node('D', None, None)
node_e = Node('E', None, None)
node_b = Node('B', node_d, node_e)
node_f = Node('F', None, None)
node_c = Node('C', None, node_f)
root = Node('A', node_b, node_c)

print('先序遍历:')
preorder_traversal(root)
print('中序遍历:')
inorder_traversal(root)
print('后序遍历:')
postorder_traversal(root)

结果是:

三种遍历结果.png



上一篇:写给媳妇儿的算法(十四)——动态规划
下一篇:写给媳妇儿的算法(十六)——二叉查找树

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