zoukankan      html  css  js  c++  java
  • 算法【普通二叉树】

    前言:

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

    二叉树通常作为数据结构应用,典型用法是对节点定义一个标记函数,将一些值与每个节点相关系。这样标记的二叉树就可以实现二叉搜索树和二叉堆,并应用于高效率的搜索和排序。

    二叉树是一个有根树,并且每个节点最多有2个子节点。非空的二叉树,若树叶总数为 n0,分支度为2的总数为 n2,则 n0 = n2 + 1。

    • 根节点
      • 柱状结构最上层的一个节点
    • 叶子节点
      • 左叶子节点
      • 右叶子节点
    • 完整的子树
      • 特性:二叉树中的任意一个节点都可以被视为另一颗子树的根节点
      • 是由根节点,左右叶子节点组成
    • 非完整的子树
      • 根节点,左叶子节点
      • 根节点,右叶子节点
      • 根节点

    广度优先遍历

    参见:广度优先搜索

    和深度优先遍历不同,广度优先遍历会先访问离根节点最近的节点。二叉树的广度优先遍历又称按层次遍历。算法借助队列实现。

    • 逐层遍历。横向遍历。
    #封装节点
    class Node():
        def __init__(self,item):
            self.item = item
            self.left = None
            self.right = None
    
    class Tree():
        def __init__(self):
            # 构建一个空树
            self.root = None
    
        def addNode(self,item):
            node = Node(item)
            #树为空
            if self.root == None:
                self.root = node
                return
            #树为非空
            cur = self.root     #根节点
            q_list = [cur]
    
            while True:
                first_item = q_list.pop(0)
                # 判断取出节点的左节点是否为空,不为空加入到列表
                if first_item.left != None:
                    q_list.append(first_item.left)
                else:
                    first_item.left = node
                    break
                #判断右叶子节点是否为空
                if first_item.right != None:
                    q_list.append(first_item.right)
                else:
                    first_item.right = node
                    break
    
        def traverse(self):
            cur = self.root
            q_list = [cur]
            while q_list:
                first_item = q_list.pop(0)
                print(first_item.item)
                if first_item.left != None:
                    q_list.append(first_item.left)
                if first_item.right != None:
                    q_list.append(first_item.right)
    tree = Tree()
    tree.addNode(1)
    tree.addNode(2)
    tree.addNode(3)
    tree.addNode(4)
    tree.addNode(5)
    tree.traverse()
    
    >>>
    1
    2
    3
    4
    5
    

    深度优先遍历

    参见:深度优先搜索

    在深度优先级中,我们希望从根结点访问最远的结点。和图的深度优先搜索不同的是,不需记住访问过的每一个结点,因为树中不会有环。前序,中序和后序遍历都是深度优先遍历的特例。

    前(先)序、中序、后序遍历

    • 深度遍历:竖向遍历。需要作用在二叉树的每一颗子树
      • 前序:根左右
      • 中序:左根右(想象成树结构整体顺时针走)
      • 后序:左右根(想象成树结构整体逆时针走)

    遍历二叉树:L、D、R分别表示遍历左子树、访问根结点和遍历右子树,则先(根)序遍历二叉树的顺序是DLR,中(根)序遍历二叉树的顺序是LDR,后(根)序遍历二叉树的顺序是LRD。还有按层遍历二叉树。这些方法的时间复杂度都是O(n),n为结点个数。

    #封装节点
    class Node():
        def __init__(self,item):
            self.item = item
            self.left = None
            self.right = None
            
    class Tree():
        def __init__(self):#构建一个空树
            self.root = None
        def addNode(self,item):
            node = Node(item)
            #如果树为空
            if self.root == None:
                self.root = node
                return
            #树为非空
            cur = self.root
            q_list = [cur]
            
            while True:
                first_item = q_list.pop(0)
                #判断取出节点的左节点是否为空,不为空加入到列表
                if first_item.left != None:
                    q_list.append(first_item.left)
                else:
                    first_item.left = node
                    break
                #判断右叶子节点是否为空
                if first_item.right != None:
                    q_list.append(first_item.right)
                else:
                    first_item.right = node
                    break
        def forward(self,root): # 前(先)序遍历
            #将根左右作用在每一颗子树中,子树和子树是基于根节点区分
            #设计一个结束递归的条件
            if root == None:
                return
            #参数root是子树的根节点
            print(root.item)
            self.forward(root.left)
            self.forward(root.right)
        def middle(self,root):	#中序遍历
            if root == None:
                return
            self.middle(root.left)
            print(root.item)
            self.middle(root.right)
        def back(self,root):	#后序遍历
            if root == None:
                return
            self.back(root.left)
            self.back(root.right)
            print(root.item)
            
    tree = Tree()
    tree.addNode(1)
    tree.addNode(2)
    tree.addNode(3)
    tree.addNode(4)
    tree.addNode(5)
    tree.addNode(6)
    
    tree.forward(tree.root)
    >>>
    1
    2
    4
    5
    3
    6
    
    tree.middle(tree.root)
    >>>
    4
    2
    5
    1
    6
    3
    
    tree.back(tree.root)
    >>>
    4
    5
    2
    6
    3
    1
    
  • 相关阅读:
    要想成为前端大神,那些你不得不知晓的web前端命名规范。
    正确开启Mockjs的三种姿势:入门参考(一)
    1024码农节-向自己致敬!
    ES6 常用总结(前端开发js技术进阶提升总结)
    JS快速构建数组方法
    React绑定事件动态化的实现方法
    JQ遇到$(‘.xxx’).attr(‘display’)一直返回undefined
    你所要掌握的最简单基础的React渲染优化
    MyBatis Generator
    Spring boot集成redis初体验
  • 原文地址:https://www.cnblogs.com/remixnameless/p/13308747.html
Copyright © 2011-2022 走看看