本章我们学习了树与二叉树,树对于我来说是一种新的概念,虽然它本身的结构比较简单,但是在认清一些概念的时候还是要费上一点功夫,我们学习到的有树的基本术语:
节点的度:节点的子树个数。
树的度:树的所有节点中最大的度数(树的度通常为节点个数的N-1
)。
叶节点:度为0
的节点(也称叶子节点)。
父节点:有子树的节点是其子树的父节点。
子节点:若A
节点是B
节点的父节点,则称B
节点是A
节点的子节点。
兄弟节点:具有同一个父节点的各节点彼此是兄弟节点。
路径和路径长度:从节点n1
到nk
的路径为一个节点序列n1,n2,n3,...,nk
,ni
是ni+1
的父节点。路径所包含边的个数为路径长度。
节点的层次:规定根节点在第0层
,它的子节点是第1层
,子节点的子节点是第2层
,以此类推。
树的深度:树中所有节点中的最大层次是这棵树的深度(因为上面是从第0层开始,深度 = 第最大层数 + 1)
还有二叉树的相关定义和性质:
二叉树的每个结点至多有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
① 在二叉树的第K层上,最多有 2k-1 (K >= 1)个结点
② 深度为K的二叉树,最多有 2k - 1 个结点(K>=1)
③ 对于任何一棵二叉树,如果其叶子结点的个数为K,度为2的结点数为M,则K=M+1
④ 对于一棵有 n 个结点的完全二叉树的结点按层次进行编号(如上图,从第一层到第 (log 2n 向下取整),每层从左到右),对任意结点 i (1<i<n),有:
→如果i=1,则结点i无父结点,是二叉树的根,如果i>1,则父结点为 i/2 向下取
→如果2i>n,则结点i为叶子结点,无左子结点,否则,其左子结点为2i
→如果2i+1>n,则结点i无右子结点,否则,其右子结点是结点2i+1
对我来说,学习花最多时间莫过于学习二叉树了,因为我相信把二叉树的定义,性质学好了,对解决一般树会有更好理解。但二叉树的性质一开始上课时会因为概念不清晰而觉得一下子有点难理解,过后认真回顾一下书本,并画了一下图来数一下
常谈的存储结构。
存储结构分为:顺序存储和链式存储。
然后学习到遍历二叉树和线索二叉树。
遍历二叉树的算法描述有三种:先序、中序、后序。
先序:
void PreOrder(BiTNode *T){ if(T){ cout<<T->data; PreOrder(T->lchild); PreOrder(T->rchild); } }
中序:
void InOrder(BiTNode *T){ if(T){ InOrder(T->lchild); cout<<T->data; InOrder(T->rchild); } }
后序:
void PostOrder(BiTNode *T){ if(T){ PostOrder(T->lchild); PostOrder(T->rchild); cout<<T->data; } }
二叉树的存储结构表示方法:(这个也是一开始在做题时最纠结的事,像这次分组讨论题目,花了1个多小时讨论到底用哪种表示方法,不过后来我发现,采用哪种方法都是可以解题的,不过写代码就会出现简单情况和复杂情况。
孩子表示法,孩子兄弟表示法,双亲表示法。
在这一单元的学习中,虽有新的知识的引入,但我觉得离不开前面线性表,栈和队这些知识的支撑,因为前面在有关线性表的对申请空间的销毁的注意,在后来有时打代码也会注意看看是否需要写destory函数。