zoukankan      html  css  js  c++  java
  • 数据结构和算法-查找算法-树和二叉树查找

     ########################################################

    """
    一、树
    1、什么是树?
    树状图是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。
    把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
    
    它具有以下的特点:
    每个节点有零个或多个子节点;
    没有父节点的节点称为根节点;
    每一个非根节点有且只有一个父节点;
    除了根节点外,每个子节点可以分为多个不相交的子树;
    
    几个概念:
    节点的度:就是节点有几个下级,
    树的度,就是最大的节点的度,就是树的度
    叶子节点,就是没有子节点了
    父节点,上一级的节点,
    子节点,就是下一级
    兄弟节点,同一个父亲的节点
    节点的层,
    树的高度或者深度,就是最大的层,
    """

     ########################################################

    """
    
    二, 二叉树
    树有有序树和无序树,我们只研究有序树中的二叉树, 1、什么是二叉树? 二叉树,就是度不差过2的树(节点最多有两个叉) 2,二叉树的分类: # 1,完全二叉树: 叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树 # 2,满二叉树 一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。 满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树 # 3,平衡二叉树 # 4,二叉排序树
    """

     ########################################################

    """
    
    三、二叉树的存储方式
    
    二叉树也可以使用顺序表进行存储,
    不过树还是使用链表存储,就是连接两个节点,
    常见的树应用的场景,html就是树的结构,
    树的应用场景是非常的多的,
    
    1、链式存储方式
    a、二叉树的链式存储:将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接。
    b、节点定义
    class BiTreeNode:
        def __init__(self,data):  #data就是传进去的节点的值
            self.data = data
            self.lchild = None
            self.rchild = None
    
    c、二叉树的遍历:
    
    I 、先(前)序遍历:访问根结点的操作发生在遍历其左右子树之前
    
       具体操作:若二叉树非空,则依次执行如下操作:
    ⑴ 访问根结点;
    ⑵ 遍历左子树;
    ⑶ 遍历右子树。
    II、中序遍历:访问根结点的操作发生在遍历其左右子树之中(间)。
    
         具体操作: 若二叉树非空,则依次执行如下操作:
    ⑴遍历左子树;
    ⑵访问根结点;
    ⑶遍历右子树。
    III、后序遍历:访问根结点的操作发生在遍历其左右子树之后。
    
          若二叉树非空,则依次执行如下操作:
    ⑴遍历左子树;
    ⑵遍历右子树;
    ⑶访问根结点。
    IV、层次遍历
    用一个队列保存被访问的当前节点的左右孩子以实现层序遍历。
    
    """

    ##################     二叉树的遍历代码        #######################

    class Node(object):
    """节点类"""
        def __init__(self, elem=-1, lchild=None, rchild=None):
            self.elem = elem
            self.lchild = lchild  # 有两个子节点
            self.rchild = rchild
    
    class Tree(object):
        """树类"""
        def __init__(self, root=None):
            self.root = root
    
        def add(self, elem):
            """为树添加节点"""
            node = Node(elem)
            #如果树是空的,则对根节点赋值
            if self.root == None:
                self.root = node
            else:
                queue = []
                queue.append(self.root)
                #对已有的节点进行层次遍历
                while queue:  # 结束的条件就是队列为空,
                    #弹出队列的第一个元素
                    cur = queue.pop(0)
                    if cur.lchild == None:
                        cur.lchild = node
                        return
                    elif cur.rchild == None:
                        cur.rchild = node
                        return
                    else:
                        #如果左右子树都不为空,加入队列继续判断
                        queue.append(cur.lchild)
                        queue.append(cur.rchild)
    
    
        # 树的遍历
        ####################################################################
        # 广度优先遍历
        def breadth_travel(self):
            """利用队列实现树的层次遍历"""
            if self.root == None:
                return
            queue = [self.root]
            while queue:
                node = queue.pop(0)
                print(node.elem)
                if node.lchild != None:
                    queue.append(node.lchild)
                if node.rchild != None:
                    queue.append(node.rchild)
    
        ##################################################################
        # 深度优先遍历
        # 有三种方式
        # 这个遍历的代码可以不用管,但是一定要会数,给你顺序,你能画出来一个二叉树,这个正推和逆推都要会
        # 先序遍历,永远都是根节点优先,中左右
        def preorder(self, root):
            """递归实现先序遍历"""
            if root == None:
                return
            print(root.elem)
            self.preorder(root.lchild)
            self.preorder(root.rchild)
    
        # 中序遍历: 左中右,
        def inorder(self, root):
            """递归实现中序遍历"""
            if root == None:  # 这是递归的结束条件
                return
            self.inorder(root.lchild)
            print(root.elem)
            self.inorder(root.rchild)
    
        # 后续遍历,左右中,
        def postorder(self, root):
            """递归实现后续遍历"""
            if root == None:
                return
            self.postorder(root.lchild)
            self.postorder(root.rchild)
            print(root.elem)
    
    
    if __name__ == '__main__':
        tree=Tree()
        tree.add(1)
        tree.add(2)
        tree.add(3)
        tree.add(4)
        tree.add(5)
        tree.breadth_travel()

    ##############################################

      

    ##############################################

     ##############################################

  • 相关阅读:
    mysql复制那点事
    全排列问题
    56. Merge Interval
    2. Add Two Numbers
    20. Valid Parentheses
    121. Best Time to Buy and Sell Stock
    120. Triangle
    96. Unique Binary Search Trees
    91. Decode Ways
    72. Edit Distance
  • 原文地址:https://www.cnblogs.com/andy0816/p/12348246.html
Copyright © 2011-2022 走看看