(一) 树的基本概念 (其实我觉得树的概念是不会考的)
树是N个节点的有限集合, N=0时, 称为空树
1) 有且仅有一个特定的节点为根
2) 其余节点又可以分为m个互不相交的有限集合, 一个集合本身又是一棵树
深度是针对节点的, 从上往下算; 高度是针对子树的, 从下往上算
有序树和无序树: 子树从左到右是不是有顺序
树的度数: 节点拥有的子树的数量. 所有节点度数之和=所有节点数-1
(二) 二叉树
定义: 每个节点至多有两棵子树, 且有左右之分, 不能颠倒 (增强版的有序树)
满二叉树: 高度为h, 含有2^h-1个结点的二叉树
完全二叉树: 每个结点都与相同高度的满二叉树中编号为1~n的节点一一对应
顺序存储结构: 适用于完全二叉树和满二叉树. 通过节点序号反应逻辑关系. 优点: 节省存储空间.
对于一般的二叉树, 要想通过下标反映逻辑关系, 只能添加一些并不存在的空结点
链式存储结构: left right data
二叉树的遍历方式: https://blog.csdn.net/yimingsilence/article/details/54783208
线索二叉树 将传统二叉链表中的空指针改为存放其直接前驱或后继的指针
遍历方法
// 求中序线索二叉树下某节点的下一个结点(左节点)
ThreadNode* FirstNode(ThreadNode* p) {
while (p->ltag == 0) p = p->lchild;
return p;
}
// 求中序线索二叉树某节点的后继结点(右结点)
ThreadNode* NextNode(ThreadNode* p) {
if (p->rtag == 0) return FirstNode(p->rchild);
else return p->rchild;
}
// 中序遍历
void InOrder(ThreadNode* T) {
for (ThreadNode* p = FirstNode(T); p != NULL; p = NextNode(p)) {
visit(p);
}
}
(三) 树、森林
存储结构:
1) 双亲表示法 存储父亲节点
2) 孩子表示法 将孩子节点用链表连起来
3) 孩子兄弟表示法 又称二叉树表示法 存储第一个孩子和下一个的兄弟
树和森林与二叉树的应用
(四) 树与二叉树的应用
树的应用: 并查集
二叉排序树(左子树上的所有值<根结点的值<右子树上所有结点的值)
常用操作: 查找 插入 构造 删除
平衡二叉树
插入: 为了保证平衡, 每次当在二叉树插入或删除一个结点时, 要检查其插入路径上的结点是否出现不平衡
参考资料: https://www.cnblogs.com/zhangbaochong/p/5164994.html
哈夫曼编码
评价方法: 带权路径长度WPL
哈夫曼树的构造: 给定N个权值为w的结点, ........