定义:
树是n(>=0)个结点的有限集,n=0时称为空树。在任意一棵非空树中,有且仅有一个特定的称为根的结点,当n>1时,其余节点可分为m个互不相交的有限集,其中每一棵树称为根的子树。
结点分类:
结点拥有的子树数称为结点的度。度为0的结点称为叶节点,度不为0的结点称为分支结点。树的度是树内各结点度的最大值。
结点间关系:
结点子树的根称为该结点的孩子,该结点称为孩子的双亲。同一双亲的孩子结点互称兄弟。从根到该结点所经分支上的所有节点称为结点的祖先。双亲在同一层的互为堂兄弟。
结点的层次与深度:
二叉树:
特点:
1.每个结点最多有两棵子树
2.左子树和右子树是有顺序的,即使某结点只有一颗子树,也要区分是左子树还是右子树。
性质:
1.在二叉树的第i层上至多有个结点(i>=1)
2.深度为k的二叉树至多有个结点(k>=1)
3.对于任何一棵二叉树T,如果其终端结点数为,度为2的结点数为
,则
=
+1
4.具有n个结点的完全二叉树深度为【】+1。(【
】表示不大于【
】的整数)
存储结构:
链式存储结构:
设置一个数据域和两个指针域
typedef struct BiTNode//结点结构
{
TElemType data;//结点数据
struct BiTNode *child,*rchild//左右孩子指针
}BiTNode,*BiTree
二叉树遍历:
1.前序遍历:若二叉树为空,则空操作返回。否则先前序遍历左子树,在前序遍历右子树。
2.中序遍历:若二叉树为空,则空操作返回。否则先中序遍历左子树,在访问根结点,最后中序遍历右子树。
3.后序遍历:若二叉树为空,则空操作返回。否则从左到右先叶子后结点,最后访问根结点。
void PostOrderTraverse(BiTree)
{
if(T==NUll)
return;
PostOrderTraverse(T->lchild);//先序遍历左子树
PostOrderTraverse(T->rchild);//后序遍历有字数
Print( "%c",T->data);//显示节点数据,可以更改为其他对结点操作
}
关于二叉树的推导:
先确定二叉树的根结点,随后根据不同排序确定二叉树。(此类题目只有先序与中序,先序与后序两种组合。先序与后序组合无法确定一棵二叉树)
建立二叉链表二叉树:
通过生成拓展二叉树来进行一次遍历,将不存在的结点通过特定符号表示为虚结点。代码如下:
线索二叉树结构的实现:
线索二叉树可以理解为二叉链表二叉树的升级版。后者只能通过一次遍历之后才能知道结点的前驱后继各是什么,而线索二叉树可以直接知道结点前驱后继的值。
ltag和rtag只存放0或1的布尔值,用于确定lchild和rchild指向哪里
赫夫曼树及其应用
路径:
两个结点间的分支构成两个结点间的路径,路径上的分支数目称作路径长度。例如二叉树a中根结点到d的路径长度为4.
树的路径长度就是从树根到每一结点的路径长度之和。例如:二叉树a的路径长度1+1+2+2+3+3+4+4=20
节点的带权路径长度为该结点到树根的路径长度与结点上权的乘积;其中带权路径长度WPL最小的二叉树称为赫夫曼树
例如:二叉树a的WPL:5*1+15*2+40*3+30*4+10*4=315
二叉树b的WPL:5*3+15*3+40*2+30*2+10*2=220