数据结构--树

树(二叉树)的基本概念

编程语言:python

作者:黑暗主宰

邮箱:shengzhanhe@gmail.com

数据结构–树

树的概念

树是一种非线性的数据结构,是由 n ( n > = 0 ) n(n >=0) nn>=0个结点组成的有限集合;它是一种类似于链表的数据结构,不过链表的结点是以线性方式简单地指向其后继结点,而树的一个结点可以指向许多个结点。它具有以下的特点:

  • 每个节点有零个或多个子节点
  • 没有父节点的节点成为根节点
  • 每一个非根节点有且只有一个父节点
  • 除了根节点外,每个子节点可以分为多个不想交的子树

在这里插入图片描述

相关术语

  • 节点的度:一个节点含有的子树的个数称为该节点的度(如上图1节点的度为2;2节点的度为1);
  • 叶子节点终端节点:度为零的节点(如节点4、5、8、9);
  • 树的度:一个树种,最大的节点的度称为树的度(如上图,0节点的度为3,所以这个数的度为3);
  • 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
  • 兄弟节点:具有相同父节点的节点称为兄弟节点(如4、5节点,1、2、3节点为兄弟节点);
  • 节点的大小:节点的大小是指子孙的个数,包括自身(如子树1的大小为2,子树3的大小为3);
  • 树的层:位于相同深度的所有节点的集合叫作树的层(如1、2、3具有相同的层,其中根节点算一层);
  • 节点的层次:从根节点开始定义,根为第一层,根的子节点为第二次,以此类推;
  • 树的深度高度:树中节点的最大层次

二叉树

二叉树的定义:每个节点最多含有两个子树的树称为二叉树,通常子树被称为左子树和右子树。

二叉树的性质:

  • 在二叉树的第 i i i层至多有 2 i − 1 {2^{{\rm{i}} - 1}} 2i1个节点 ( i > 0 ) (i>0) i>0
  • 深度为 k k k 的二叉树至多 2 m − 1 2^m-1 2m1 个节点 ( k > 0 ) (k>0) (k>0)
  • 对于任意一颗二叉树,如果其叶节点数为 N 0 N_0 N0,而度数为2的节点总数为 N 2 N_2 N2, 则 N 0 = N 2 + 1 N_0 = N_2 + 1 N0=N2+1。(对于这个性质的证明可以看这个博客
  • 具有 n n n 个节点(这里的节点不包括叶子节点)的完全二叉树的深度必为 log ⁡ 2 ( n + 1 ) \log 2\left( {n + 1} \right) log2(n+1)
  • 对完全二叉树,若从上至下、从左到右编号,则编号为 i i i 的节点,其做孩子编号必为 2 i 2i 2i, 其右孩子编号必为 2 i + 1 2i+1 2i+1;其双亲的编号必为 i / 2 i/2 i/2 i = 1 i=1 i=1 时为根除外)

二叉树的遍历

对于二叉树的遍历,主要分为三种:先序遍历、中序遍历和后续遍历(还有一个层次遍历可以算是第四种吧)。

在这里插入图片描述

如上图,先序遍历(根->左->右)是:145;中序遍历(左->根->右)是(415);后续遍历(左->右->根)是451,即根节点的位置决定遍历的种类。

对于复杂一点的二叉树,看下图

在这里插入图片描述

在上述,先序、中序、后续三种遍历中,给出两种方式就可以写出整个树,其中必须要包括中序

代码实现树的遍历

节点的构建

class Node(object):
    def __init__(self, item):
        self.elem = item
        self.lchild = None
        self.rchild = None

然后使用上述节点构建树,并实现树节点的添加、层次遍历、前序遍历、中序遍历和后序遍历。

class Tree(object):
    
    def __init__(self):
        self.root = None
    
    def add(self, item):
        node = Node(item)
        # 根节点为空的特殊清楚
        if self.root is None:
            self.root = node
            return
        
        queue = [self.root]
        while queue:
            cur_node = queue.pop(0)
            if cur_node.lchild is None:
                cur_node.lchild = node
                return
            else:
                queue.append(cur_node.lchild)
            
            if cur_node.rchild is None:
                cur_node.rchild = node
                return
            else:
                queue.append(cur_node.rchild)
    
    def breadth_travel(self):
        #根节点为空的情况
        if self.root is None:
            return
        queue = [self.root]
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.elem, end = ' ')
            if cur_node.lchild is not None:
                queue.append(cur_node.lchild)
            if cur_node.rchild is not None:
                queue.append(cur_node.rchild)
    '''
    先序遍历
    '''
    def preorder(self, node):
        
        if node is None:
            return
        print(node.elem, end=" ")
        self.preorder(node.lchild)
        self.preorder(node.rchild)
    
    '''
    中序遍历
    '''
    def inorder(self, node):
        if node is None:
            return 
        self.inorder(node.lchild)
        print(node.elem, end=" ")
        self.inorder(node.rchild)
    
    '''
    后序遍历
    '''
    def postorder(self, node):
        if node is None:
            return
        self.postorder(node.lchild)
        self.postorder(node.rchild)
        print(node.elem, end=" ")

代码测试

tree = Tree()
tree.add('0')
tree.add('1')
tree.add('2')
tree.add('3')
tree.add('4')
tree.add('5')
tree.add('6')
tree.add('7')
tree.breadth_travel()
print()
tree.preorder(tree.root)
print()
tree.inorder(tree.root)
print()
tree.postorder(tree.root)

欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步
在这里插入图片描述

注: 文中有写错的地方,欢迎大家不吝指正!!!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值