二叉树与遍历的Python实现

来源:互联网 发布:慈溪行知职高大学生 编辑:程序博客网 时间:2024/06/05 14:29

  • 二叉树简介
  • 具体实现
    • 节点
    • 二叉树
  • 遍历
    • 深度优先算法DFS
      • 先序遍历
      • 中序遍历
      • 后序遍历
    • 广度优先算法BFS

二叉树简介

在计算机科学中,二叉树(Binary tree)是每个节点最多只有两个分支(不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”和“右子树”。二叉树的分支具有左右次序,不能颠倒。

具体实现

节点

class node(object):    def __init__(self, val):        self.val = val        self.left = None        self.right = None

二叉树

class BinaryTree(object):    def __init__(self):        #初始化链表为空表        self.root = None         self.nodeLayer = dict()    # 根据输入的BFS的数据生成二叉树    def initBinaryTree(self, *data):        if data == None:            raise ValueError('root node need one number')        #  层数,从0开始        layerCount = 0          length = len(data)        # 补为偶数        if length%2 != 0:            list(data).append('#')            length += 1        while self.power(2,layerCount) < length+1:            self.nodeLayer[str(layerCount)] = list()            start = self.power(2,layerCount)-1            stop = min(start*2+1,length)            if layerCount == 0:                self.nodeLayer[str(layerCount)].append(node(data[0]))                self.root = self.nodeLayer[str(layerCount)][0]            else:                nodeCount = 0                for p,q in zip(range(start,stop,2),range(start+1,stop,2)):                    self.nodeLayer[str(layerCount)].append(node(data[p]))                    self.nodeLayer[str(layerCount)].append(node(data[q]))                    # 上层节点                        tmpNode = self.nodeLayer[str(layerCount-1)][nodeCount]                    tmpNode.left = self.nodeLayer[str(layerCount)][p-self.power(2,layerCount)+1]                    tmpNode.right = self.nodeLayer[str(layerCount)][q-self.power(2,layerCount)+1]                    nodeCount += 1            layerCount += 1    def power(self, x, n):        s = 1        while n > 0:            n = n - 1            s = s * x        return s

根据输入的列表建立二叉树,输入的数据和建立二叉树的过程都按照广度优先(BFS),比如

  1 / \2   3

对应的列表为[1,2,3]

为了区分下面的两种情况:

  1 /2

1 \  2

分别写作[1,2,'#'][1,'#',2]

    1   / \  2   3 / \   \4   5   6   / \  7   8

对于这个二叉树,就可以序列化为[1,2,3,4,5,'#',6,'#','#',7,8],其中

1: the root2: left child of 13: right child of 14: left child of 25: right child of 2#: left child of 36: right child of 3#: left child of 4#: right child of 47: left child of 58: right child of 5

可以使用代码

tree = BinaryTree()data = [1,2,3,4,5,'#',6,'#','#',7,8]tree.initBinaryTree(*data)

得到上面的二叉树

遍历

深度优先算法(DFS)

深度优先搜索算法(Depth-First-Search,简称DFS)是一种盲目搜索算法,用于遍历或搜索树或图。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。

从图中,可以直观的看出搜索的顺序:


这里写图片描述

先序、中序和后序遍历都是深度优先搜索算法的特例
L、D、R分别表示遍历左子树、访问根结点和遍历右子树,先序遍历二叉树的顺序是DLR,中序遍历二叉树的顺序是LDR,后序遍历二叉树的顺序是LRD。

先序遍历

DLR_list = []def DLR(node):    DLR_list.append(node.val)    if node.left  != None:        DLR(node.left)    if node.right != None:        DLR(node.right)    return DLR_list

运行一下

print(DLR(tree.root))[1, 2, 4, '#', '#', 5, 7, 8, 3, '#', 6]

中序遍历

LDR_list = []def LDR(node):    if node.left  != None:        LDR(node.left)    LDR_list.append(node.val)    if node.right != None:        LDR(node.right)    return LDR_list

运行一下

print(LDR(tree.root))['#', 4, '#', 2, 7, 5, 8, 1, '#', 3, 6]

后序遍历

LRD_list = []def LRD(node):    if node.left  != None:        LRD(node.left)    if node.right != None:        LRD(node.right)    LRD_list.append(node.val)    return LRD_list

运行一下

print(LRD(tree.root))['#', '#', 4, 7, 8, 5, 2, '#', 6, 3, 1]

广度优先算法(BFS)

广度优先搜索算法(Breadth-First-Search,缩写为BFS),又译作宽度优先搜索,或横向优先搜索,也是一种盲目搜索算法,用于遍历或搜索树或图。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点,如果所有节点均被访问,则算法中止。


这里写图片描述

在上面的二叉树的初始化过程中就是遵循BFS的规则

由于本人水平有限,难免出现错漏之处,欢迎批评指正

原创粉丝点击