数据结构与算法之二叉树广度遍历、深度遍历总结

什么是树,它是和链表一样都是一种抽象数据类型(ADT),包括数据结构和对数据的操作。
树是一种二维平面的数据结构结构,它也是由节点组成的,只是它的后继节点不止一个,而链表的后继节点只有一个。

树具有以下特点:
①每个节点有零个或多个子节点;
②没有父节点的节点称为根节点;
③每一个非根节点有且只有一个父节点;
④除了根节点外,每个子节点可以分为多个不相交的子树;

在这里插入图片描述

先来介绍一种典型的树类型:二叉树(上图不是个二叉树,因为根节点就不满足只有两个子树的条件
定义:每个结点最多含有两个子树的树称为二叉树。
二叉树有很多种:二叉树、完全二叉树、满二叉树、线索二叉树、霍夫曼树、二叉排序树、平衡二叉树、红黑树
关于树有很多专业术语:
根结点,叶子结点,深度,堂兄弟结点,兄弟结点,层等等

满足二叉树的前提条件下,又衍生出完全二叉树和满二叉树:
完全二叉树:假设树的深度的是h,那么除了h层之外,其余层节点数达到最大,且第h层所有的节点都连续集中在最左边,这就是完全二叉树。
在这里插入图片描述
满二叉树:除最后一层外,其余结点都含有两个子结点,达到每层均是满的结点数。
在这里插入图片描述
有了树的模型,那么树是怎么来存储呢,有两种方式:顺序存储和链表存储。
有了存储的方式,那么就是对树如何进行操作了,这里暂时只介绍增加结点和遍历树中的结点
下面来介绍如何遍历二叉树:
遍历二叉树有两种方式:BFS和DFS
BFS就是广度遍历,就是一层一层的遍历。从第一层根结点开始。然后第二层:左结点,右结点,依次类推,最后是到叶子结点遍历完成。
DFS就是:深度遍历,分为先序遍历,中序遍历,后序遍历。
先序遍历:从树的根节点开始,然后左结点,右节点。
中序遍历:先从树的根节点的左结点开始,遍历根结点,遍历右节点
后序遍历:先从树的根节点的左节点开始,然后遍历右节点,最后遍历根节点。
下面通过代码来实现树,并进行广度遍历。这里使用的是队列:

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

#创建一个树
class Tree(object):
    def __init__(self,node=None):
        self.root = node

    #增加结点
    def add(self,item):
        node = Node(item)
        if self.root == None:
            self.root = node
            return
        queue = [self.root] #使用队列来操作

        while queue:
            cur = queue.pop(0)
            if cur.lchild == None:
                cur.lchild = node
                return
            else:
                queue.append(cur.lchild)
            if cur.rchild == None:
                cur.rchild = node
                return
            else:
                queue.append(cur.rchild)
    #树的广度遍历
    def travel_bfs(self):
        queue = [self.root]
        if self.root == None:
            return
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.val,end='\t')
            if cur_node.lchild != None:
                queue.append(cur_node.lchild)
            if cur_node.rchild != None:
                queue.append(cur_node.rchild)



t = Tree()
t.add(1)
t.add(2)
t.add(3)
t.add(4)
t.add(5)
t.travel_bfs()

运行结果:

1	2	3	4	5

下面介绍树的深度遍历:先序遍历,中序遍历,后序遍历。主要使用的是递归:
例:先序遍历

#创建一个结点
class Node(object):
    def __init__(self,item=None):
        self.val = item
        self.lchild = None
        self.rchild = None

#创建一个树
class Tree(object):
    def __init__(self,node=None):
        self.root = node

    #增加结点
    def add(self,item):
        node = Node(item)
        if self.root == None:
            self.root = node
            return
        queue = [self.root] #使用队列来操作

        while queue:
            cur = queue.pop(0)
            if cur.lchild == None:
                cur.lchild = node
                return
            else:
                queue.append(cur.lchild)
            if cur.rchild == None:
                cur.rchild = node
                return
            else:
                queue.append(cur.rchild)
    #树的广度遍历
    def travel_bfs(self):
        queue = [self.root]
        if self.root == None:
            return
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.val,end = ' ')
            if cur_node.lchild != None:
                queue.append(cur_node.lchild)
            if cur_node.rchild != None:
                queue.append(cur_node.rchild)
    def preorder(self,root_node):
        if root_node == None:
            return
        print(root_node.val,end = ' ')
        self.preorder(root_node.lchild)
        self.preorder(root_node.rchild)




t = Tree()
t.add(0)
t.add(1)
t.add(2)
t.add(3)
t.add(4)
t.add(5)
t.add(6)
t.add(7)
t.add(8)
t.add(9)
t.travel_bfs()
print()
t.preorder(t.root)

运行结果:

0 1 2 3 4 5 6 7 8 9 
0 1 3 7 8 4 9 2 5 6 

例:中序遍历和后序遍历

#创建一个结点
class Node(object):
    def __init__(self,item=None):
        self.val = item
        self.lchild = None
        self.rchild = None

#创建一个树
class Tree(object):
    def __init__(self,node=None):
        self.root = node

    #增加结点
    def add(self,item):
        node = Node(item)
        if self.root == None:
            self.root = node
            return
        queue = [self.root] #使用队列来操作

        while queue:
            cur = queue.pop(0)
            if cur.lchild == None:
                cur.lchild = node
                return
            else:
                queue.append(cur.lchild)
            if cur.rchild == None:
                cur.rchild = node
                return
            else:
                queue.append(cur.rchild)
    #树的广度遍历
    def travel_bfs(self):
        queue = [self.root]
        if self.root == None:
            return
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.val,end = ' ')
            if cur_node.lchild != None:
                queue.append(cur_node.lchild)
            if cur_node.rchild != None:
                queue.append(cur_node.rchild)
    def preorder(self,root_node):
        '''先序遍历'''
        if root_node == None:
            return
        print(root_node.val,end = ' ')
        self.preorder(root_node.lchild)
        self.preorder(root_node.rchild)

    def midorder(self,root_node):
        '''中序遍历'''
        if root_node == None:
            return
        self.midorder(root_node.lchild)
        print(root_node.val,end = ' ')
        self.midorder(root_node.rchild)
        
    def postorder(self,root_node):
        '''后序遍历'''
        if root_node == None:
            return
        self.postorder(root_node.lchild)
        self.postorder(root_node.rchild)
        print(root_node.val,end = ' ')

t = Tree()
t.add(0)
t.add(1)
t.add(2)
t.add(3)
t.add(4)
t.add(5)
t.add(6)
t.add(7)
t.add(8)
t.add(9)
t.travel_bfs()
print()
t.preorder(t.root)
print()
t.midorder(t.root)
print()
t.postorder(t.root)

运行结果:

0 1 2 3 4 5 6 7 8 9 
0 1 3 7 8 4 9 2 5 6 
7 3 8 1 9 4 0 5 2 6 
7 8 3 9 4 1 5 6 2 0 

附上别人写的挺详细的文章:
https://blog.csdn.net/u012060033/article/details/107128291/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如梦@_@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值