Python数据结构与算法——Day8
树与树算法
树是一种抽象的数据类型,它是由n(n>=1)个有限节点组成的一个具有层次关系的集合。树其实是一颗“倒挂的树”,即,根朝上,叶朝下,它具有如下特点:
- 每个节点有零个或多个子节点;
- 没有父节点的节点称为根节点;
- 每一个非根节点有且只有一个父节点;
- 除了根节点外,每个子节点可以分为多个不相交的子树;
其结构:
相关术语
- 节点的度:一个节点含有的子树的个数称为该节点的度;
- 树的度:一棵树中,最大的节点的度称为树的度;
- 叶节点或终端节点:度为零的节点;
- 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
- 子节点:一个节点含有的子树的根节点称为该节点的子节点;
- 兄弟节点:具有相同父节点的节点互称为兄弟节点;
- 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
- 树的高度或深度:树中节点的最大层次;
- 堂兄弟节点:父节点在同一层的节点互为堂兄弟;
- 节点的祖先:从根到该节点所经分支上的所有节点;
- 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
- 森林:由m(m>=0)棵互不相交的树的集合称为森林;
树的种类
- 无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树
- 有序树:树中任意节点的子节点之间存在顺序关系,具体分为:
2.1. 二叉树:每个节点最多含有两个子树的树
2.2. 哈夫曼树:带权路径最短的二叉树称为哈夫曼树或者最优二叉树
2.3. B树
二叉树
- 完全二叉树:
对于一颗二叉树,假设其深度为d(d>1)。除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右连续地紧密排列,这样的二叉树被称为完全二叉树,其中满二叉树的定义是所有叶节点都在最底层的完全二叉树; - 平衡二叉树(AVL):
当且仅当任何节点的两棵子树的高度差不大于1的二叉树; - 排序二叉树,也称二叉搜索树
二叉树的节点表示及树的创建
class Node:
def __init__(self,item):
self.elem=item
self.lchild=None
self.rchild=None
class Tree:
def __init__(self):
self.root=None
# 优先添加左子树
def add(self,item):
node=Node(item)
if self.root == None:
self.root=node
return
queue=[self.root]
while queue:
cur_node=queue.pop(0)
if cur_node.lchild == None:
cur_node.lchild=node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild == None:
cur_node.rchild=node
return
else:
queue.append(cur_node.rchild)
二叉树的遍历
遍历树是指对树中所有节点的信息的访问,每个节点访问且仅访问一次,两种访问模式分别为:
- 深度优先遍历,一般通过递归实现
- 广度优先遍历,一般通过队列实现
深度优先遍历
def preorder(self,node):
'''
前序遍历,根、左、右
'''
if node==None:
return
print(node.elem)
self.preorder(node.lchild)
self.preorder(node.rchild)
def inorder(self,node):
'''
中序遍历,左、根、右
'''
if node==None:
return
self.inorder(node.lchild)
print(node.elem)
self.inorder(node.rchild)
def postorder(self,node):
'''
后序遍历,左、右、根
'''
if node==None:
return
self.postorder(node.lchild)
self.postorder(node.rchild)
print(node.elem)
广度优先遍历(层次遍历)
从树的root开始,从上至下从左至右遍历整棵树的节点
def breadth_travel(self):
'''
广度遍历(层次遍历),从上到下,从左到右
'''
if self.root == None:
return
queue=[self.root]
while queue:
cur_node=queue.pop(0)
print(cur_node.elem)
if cur_node.lchild != None:
queue.append(cur_node.lchild)
if cur_node.rchild != None:
queue.append(cur_node.rchild)