python 二叉树

无序树:树中任意节点的子节点之间没有有顺序关系,这种树成为无序树,也成为自由树

有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树

  • 二叉树:每个节点最多含有两个子树的树称为二叉树
  • 完全二叉树:除了最后一层,每层节点都达到最大数量
  • 满二叉树:所有层的结点都达到最大数量
  • 排序二叉树(二叉查找树(BinarySearch Tree), 也称二叉搜索树,有序二叉树)
  • 霍夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树
  • B树:一种对读写操作进行优化的自平衡的二叉树查找,能够保持数据有序,拥有多余两个子树

二叉树特性
度数就是它有几个子节点 度数为2的有3个节点

  • 完全二叉树——二叉树除了最后一层,其他层结点都达到最大个数,就是完全二叉树。
  • 满二叉树——除了叶结点外,每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
  • 性质1:在二叉树的第i层上至多有2^(i-1)个结点(i>0)。 如果在第三层 2^(3-1)= 4 有4个节点
  • 性质2:深度为k的二叉树至多有2^k - 1个结点(k>0)。 深度为3 2^3-1= 7 有7个节点
  • 性质3:对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1。 3+1=4
  • 性质4:具有n个结点的完全二叉树的深度必为log2(n+1)。
  • 性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i其右孩子编号必为2i+1,其父节点的编号必为i/2(i=1 时为根,除外)。

在这里插入图片描述

什么是二叉树的遍历

  1. 指对树中所有结点的数据的访问,即依次对树中每个结点访问一次且仅访问一次,把这种对所有节点的访问称为遍历(traversal)。
  2. 树的两种重要的遍历模式:深度优先遍历和广度优先遍历。
  3. 深度优先一般用递归,广度优先一般用队列。
  4. 一般情况下能用递归实现的算法大部分也能用栈来实现。

遍历

  • 前序遍历:根左右
  • EACBDGF
  • 中序遍历:左根右
  • ABCDEGF
  • 后序遍历:左右根
  • BDCAFGE
  • 层次遍历:从上到下,从左到右
  • EAGCFBD

深度优先遍历

  • 对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
  • 深度遍历有重要的三种方法,这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。
  • 三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。

二叉树的定义

  • 树中每个节点最多只能有两棵树,即每个节点的度最多为2。
  • 二叉树的子树有左右之分,即左子树与右子树,次序不能颠倒。
  • 二叉树即使只有一个子树时,也要区分是左子树还是右子树。

二叉树的链式存储: 将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接

在这里插入图片描述

from collections import deque

class BiTreeNode:
    def __init__(self, data):
        self.data = data
        self.lchild = None   # 左孩子
        self.rchild = None # 右孩子

a = BiTreeNode("A")
b = BiTreeNode("B")
c = BiTreeNode("C")
d = BiTreeNode("D")
e = BiTreeNode("E")
f = BiTreeNode("F")
g = BiTreeNode("G")

#e的左边是a,右边是G
#a的右孩子是c
#c的左孩子是b,c的右孩子是d
#g的右的孩子是f


e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f

#跟节点
root = e
#链表形式
print(root.lchild.rchild.data)

在这里插入图片描述
树的遍历

前序: 先从左边开始,左完了在是右边

在这里插入图片描述
后序 BDCAFGE
层次遍历 EAGFBD

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from collections import deque

class BiTreeNode:
    def __init__(self, data):
        self.data = data
        self.lchild = None   # 左孩子
        self.rchild = None # 右孩子

a = BiTreeNode("A")
b = BiTreeNode("B")
c = BiTreeNode("C")
d = BiTreeNode("D")
e = BiTreeNode("E")
f = BiTreeNode("F")
g = BiTreeNode("G")

#e的左边是a,右边是G
#a的右孩子是c
#c的左孩子是b,c的右孩子是d
#g的右的孩子是f


e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f

#跟节点
root = e
print(root.lchild.rchild.data)
#前序
def pre_order(root):
    if root:
    	#访问跟节点
        print(root.data, end=',')
        #访问左子树
        pre_order(root.lchild)
        #访问右子树 
        pre_order(root.rchild)
#中序,左子树A是根节点,左边没有,右边是BCD,在BCD中,C是中间,C的左是B,右边是D
def in_order(root):
    if root:
    	#先递归左子树
        in_order(root.lchild)
        #访问自己
        print(root.data, end=',')
        in_order(root.rchild)

#后续遍历 左右根 
#根是在最后,所有左边的根就是在最后
def post_order(root):
    if root:
        post_order(root.lchild)
        post_order(root.rchild)
        print(root.data, end=',')
  
#先是空队,e进去了,e走了,ag进去了,a出队了,c进去了,g出队,f进队,c出队bd进队,fbd出队都没有孩子**
def level_order(root):
	#空队列 
    queue = deque()
    queue.append(root)
    while len(queue) > 0: # 只要队不空
    #出队
        node = queue.popleft()
        print(node.data, end=',')
        #左孩子有
        if node.lchild:
            queue.append(node.lchild)
        if node.rchild:
            queue.append(node.rchild)


pre_order(root)
print("-------------")
in_order(root)
print("-------------")
post_order(root)
print("-------------")
level_order(root)
print("-------------")

在这里插入图片描述

参考文章
https://blog.csdn.net/yht201293018/article/details/81198827

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伟伟哦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值