4_树
树是n(n≥0)个结点的有限集。在任意一棵非空树中:
(1)有且仅有一个特定的称为根的结点;
(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,…,Tm,其中每一个集合本身又是一棵树,并且称为根的子树。
树作为一种逻辑结构,显然是一种递归的结构,同时也是一种分层结构。
性质:
1、n个结点的树中有n-1条边
2、树中结点数等于所有结点度数加1
3、度为m的树中第i层上至多有mi-1个结点(i>=1)(即算作每个结点的度为m,这样多一层便多一次方倍(除去第一层根结点所以-1))
4、高度为h的m叉树至多有(mh-1)(m-1)个结点。(mh+mh-1+...+m+1=(mh-1)(m-1))
5、具有n个结点的m叉树的最小高度为 logm(n(m-1)+1) (推理不出,死记)
基本操作:
插入类:初始化置空、按定义创建、结点赋值、插入树作为子树
删除类:树清空、销毁结构、删除结点的子树
查找类:根结点、当前结点、当前结点双亲结点、当前节点左/右子节点、当前节点最左/右子结点、、判空、求深、遍历
二叉树
特殊二叉树:满二叉树、完全二叉树、二叉排序树、平衡二叉树
性质:
1、二叉树上子结点数等于度为2的结点数加1
2、1)二叉树的第 i 层上至多有个结点
2)深度为 k 的二叉树上至多含 个结点
4、1)具有 n 个结点的完全二叉树的深度为
2)结点 i 所在的深度为log2i+1。
5、完全二叉树标上顺序编号,则对其中任意一个编号为 i 的结点:
1)若 i=1,则该结点是二叉树的根无双亲,否则有双亲,偶为左子奇为右子,编号 i/2 或 (i-1)/2 的结点分别为双亲结点;
2)若2i>N或2i+1>N,i分别无左子或右子,否则结点 i 的左子为2i或右子为2i+1;
顺序存储结构
适用满二叉树和完全二叉树,对于一般二叉树就用0来表示没有结点的位置
注意:数组下标从1开始,二叉树的顺序存储与树的顺序存储之间关系
链式存储结构
二叉树遍历
二叉树的应用是在遍历为基础上,进行查找、添加、删除,与线性表的应用的分类上不大一样。
前序遍历 中序遍历 后序遍历
非递归遍历:非递归遍历(栈) 层次遍历(队列)
应用:输入结点值,构造二叉树 (先序遍历) 统计二叉树中叶子结点的个数 (先序遍历) 求二叉树的深度 (后序遍历)
线索二叉树
二叉树的指针域是结点数的2倍,n个结点的二叉树有2n个指针域,有n-1条边(除了根结点外每个结点都有一条边指向),即有n-1个含边的非空指针域,由此空指针域可由指针域与非空指针域做差得到:2n-(n-1)=n+1 个,且存在于叶结点。
利用这些空结点一方面避免存储资源浪费,更重要的另一方面,在二叉树链表上仅知道每个结点的左右子,若每次想知道某结点前驱后继就需要遍历一次,利用这些空指针域做线索化就能将二叉树转化为一个双向链表,对查找、插入、删除结点带来了方便。
为此增设两个标志域ltag和rtag存放bool值(占内存小于指针变量lchild和rchild)。
树、森林
树的存储结构:
双亲表示法(带指针域的数组,每个元素(结点)指针域指向自己的双亲结点)、便于寻找结点双亲,寻找子女需遍历
孩子表示法(在双亲表示法基础上,将指针域改为指向自己的子结点,并且被指向的结点具有同样结构,同样地其指针域同样指向自己子结点,这样就形成了自上而下的链表,第一列为头结点,没有子结点的结点指向NULL)、便于寻找结点子女,寻找双亲需遍历
以上两种方法可以合二为一
孩子兄弟表示法(二叉树结点链,只不过左指针指向左边第一个孩子,右指针指向自己的右边下一个兄弟,从根结点开始)、方便转化为二叉树,易于查找结点子女,缺点是难找双亲,可以每个结点加一个parent域指向其双亲来解决
树、森林与二叉树的转化
1.孩子兄弟法使森林中每棵树—>二叉树。2.以第一棵树的二叉树作为根结点树,然后依次接上左子
孩子兄弟表示法可以将普通树转化成二叉树存储,在实际操作中,可以应用二叉树的性质来解决普通树或者森林的问题。
树的应用—并查集