树的概念: 树是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据集合,由n>=1个有限节点组成一个具有层次关系的集合
—每个节点有零个或多个子节点;
—没有父节点的节点称为根节点
—每一个非根节点有且只有一个父节点
—除了根节点外,每个子节点可以分成多个不相交的子树
树的一些术语:
(1)节点的度:一个节点含有的子树的个数称为该节点的度
(2)树的度:一棵树中,最大节点的度
(3)叶节点:度为零的节点
(4)父节点:一个节点含有子节点,则这个节点称为该节点的子节点
(5)子节点:一个节点含有的子树节点,称为该节点的子节点
(6)兄弟节点:具有相同的父亲节点的节点互称为兄弟
(7)节点的层次:从根节点定义开始,根为第一层,根的子节点为第二层,以此类推
(8)树的高度或深度:树中节点的最大层次
(9)堂兄弟节点:父节点在同一层的节点互为堂兄弟
(10)节点的祖先:从根到该节点的分支上所有节点
(11)子孙:以某节点为根的子树中任一节点都称为该节点的子孙
(12)森林:由n棵互不相交的树集合组成森林
树的种类:
(1)无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树
(2)有序树:
–(1)二叉树:每个节点最多含有两个子树的树称为二叉树,二叉树的类型:完全二叉树、平衡二叉树、排序二叉树
–(2)霍夫曼树
–(3)B树
树的存储
(1)顺序存储:将数据结构存储在固定的数组中,遍历速度有优势,但是所占空间比较大
(2)链式存储:二叉树通常使用链式存储,缺陷,就是指针域指针的个数不定,解决方案:把多叉树转换成二叉树来处理
由于对节点的个数无法掌握,常见树的存储表示都转换成二叉树来进行处理,子节点的个数最多为2
常见的一些树的应用场景
1.xml、html等,那么编写这些东西的解析器的时候,不可避免用到树
2.路由协议就是使用了树的算法
3.mysql数据库索引
4.文件系统的目录结构
5.所以很多经典的AI算法其实都是树搜索,此外机器学习中的decision tree也是树结构
树在现实生活中使用是非常常见的
二叉树:二叉树是每个节点最多有两个子树的树结构,通常子树被称为左子树和右子树
二叉树的特性:
(1)性质1: 在二叉树的第i层上至多有2^(i-1)个节点
(2)深度为k的二叉树至多有2^i - 1个节点
(3)任意二叉树,如果其叶节点数为N0,而度数为2的节点总数N1,则N0 = N1 + 1
(4)具有n个节点的完全二叉树的深度必有:log(n+1)
二叉树的种类:
完全二叉树:除了最后一层外,其他各层的节点数都达到最大个数,叶子节点从左到右依次排布
满二叉树:除了叶子节点外每一个结点都有左右子叶且叶子节点都处在最底层的二叉树,每层都挂满了节点
二叉树的数据结构:python实现
节点的数据结构:数据区、左链接区、右链接区
class Node(object):
"""节点类"""
def __init__(self, elem=0, 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)