数据结构|树
五、树
(一)基本概念
1.定义:n个节点构成的一个层次结构(n=0,空树,n>0,只有各个节点,其余节点互不相交)
2.基本术语:
父节点(双亲)与子节点(孩子)
如A是B、C、D的父节点,B、C、D是A的孩子,除根节点外,每个节点有且只有1个父节点祖先与子孙:如A、B是E的祖先,B、C、D、E、F是A的子孙
兄弟:具有同一父节点,如B、C、D是兄弟
堂兄弟:父节点在同一层
根节点:非空树中无前驱节点的结点,1个,无父节点
叶节点:无子节点
分支节点:其余节点的入度(ID):指向节点的分支数目
节点的出度(OD):子节点数
树的度(TD):max(所有节点的出度)
如OD(A)=3,OD(B)=1。叶节点的出度为0.
根的入度为0,其它各节点的入度=1.度=K
的树称为K叉树,但二叉树有特定的定义。有序树:树中任一节点的各子树从左到右有序
无序树:否则森林(或树林):m(m≥0)棵互不相交的有序树的有序集合
3.性质:
- 树中节点总数n(n≥0)等于树中各节点的出度之和加1 。
- 度=K的树(K叉树)第i(i≥1)层至多有Ki-1个节点。
- 深度=h(h≥1)的K(K>1)叉树至多有(Kh-1)/(K-1)个节点。
- 包含n(n≥0)个节点的K(K>1)叉树的最小深度为: $\left\lceil \log_K \left( n(K-1) + 1 \right) \right\rceil$
(二)二叉树
1.定义:或者是空树, 或者由1个根节点以及左子树和右子树组成,左子树和右子树都是二叉树。
2.特点:区分左右
性质:
- 二叉树的第i层上至多有$2^{i-1}$个节点(满二叉树),至少得有一个节点
- 深度为k的二叉树至多有$2^k-1$个节点(k>=1)
- 设二叉树BT中叶节点数为$n_0$,出度为2的节点数为$n_2$,则有:$n_0=n_2+1$
- 含有n(n ≥1)个节点的完全二叉树(与满二叉树编号一一对应/除了最后一层外,其余各层的节点都达到了最大数目,且最后一层的所有节点都从左向右连续排列)的深度:$h = \left\lfloor \log_2 n \right\rfloor + 1$
2*边 = 入度+出度
- 编号 略
3.五种基本形态:
4.案例
数据压缩问题(编码)、求表达式的解
5.抽象数据类型定义:略
D\R\P
6.存储结构
(1)顺序存储(按满二叉树编号)
优点:简单
缺点:不利于增删改;浪费空间,不适合非完全二叉树
(2)链式存储
二叉链表:
1 | struct BiNode { |
三叉链表
1 | struct TriNode { |
7.遍历二叉树
(1)前序遍历(DLR)eg.ABELDHMIJ 前缀表达式(波兰式)
(2)中序遍历(LDR)eg.ELBAMHIDJ 中缀
(3)后序遍历(LRD)eg.LEBMIHJDA 后缀(逆波兰式)
反过来,由序列得到二叉树(先序+中序 后序+中序)
实现:利用二叉链表(每个节点经过三次,三种遍历访问时机不同 时间O(n)
空间O(n)
)
(1)递归算法
(先序遍历)
1 | bool PreOrderTraverse(BiTree T){ |
(中序遍历)
1 | bool InOrderTraverse(BiTree& T) |
(后序遍历)
1 | bool PostOrderTarverse(BiTree& T) |
(2)非递归算法
(中序遍历)利用栈
1 | bool InOrderTraverse(BiTree T) |
(3) 层次遍历—利用队列
1 | void LevelOrderTraverse(BiTree T) |
(4)建立二叉树
1 | bool CreatBiTree(BiTree& T) |
(5)复制二叉树
1 | bool CopyBiTree(const BiTree& T, BiTree& NewT) |
(6)计算二叉树深度
1 | int Depth(BiTree &T) |
(7)计算节点个数
1 | int CountNode(BiTree& T) |
(8)计算叶子节点个数
1 | int Count0Node(BiTree& T) |
8.线索二叉树
利用空指针域(n+1),左孩子为空,将空左孩子指针域指向其前驱,右->后继
增设两个标志域,ltag,rtag