树形结构是元数据素(节点)之间有分支,并且具有层次关系的结构,可用于表示数据元素之间存在的一对多关系
树是由n(n>=0)个节点构成的有限集合,当n=0时称为空树。若树非空,则有以下两个性质
(1)有且仅有一个特定的节点,此为根(Root);
(2)其余的节点可分为m个互不相交的集合T1 ,T2, T3, ... ,Tm , 其中每一个集合是一棵树,并且称为根的子树
树节点: 树中一个独立单元。
树根: 树中唯一没有前驱的节点
节点的度: 节点拥有的子树数
树的度: 树中各节点的度的最大值
树叶: 度为零的节点
树的层次和深度: 从根算起,根为第一层,根的孩子为第二层,树的任意节点的层次等于它的父节点的层次加一。
树中各节点层次的最大值称为树的深度
有序树和无序数:如果树中节点的各子树从左到右是有此序的(即不能互换),则为有序树,否则为无序;
森林: m(m>=0)颗互不相交的树的集合。对树中每个节点而言,其子树的集合即为森林
图形表示法,凹入表示法,嵌套集合表示法, 广义表表示法, 层号表示法
对树中的所有节点进行访问,且每个节点仅访问一次,这就是树的遍历.
可把对节点的访问看成打印节点的关键字,数据项,或节点编号,把遍历看成是按序输入节点表
1.树的选根遍历: 首先访问根节点n, 其次依次按选根遍历T1,按选根遍历T2, ...
2.树的后根遍历: 选按后根遍历n的所有子树T1 , T2 , ..., Tm , 最后访问根节点n
二叉树是度为2的有序树
(1) 由n(n>=0)各节点所构成的集合,可以为空
(2)二叉树的根节点下可分为两个互不相交的子树,子树有左右之分,次序不能颠倒,称为左子树和右子树;
且左右子树均为二叉树
性质一: 在二叉树的第i层上最多有2^(i-1) 个节点
性质二: 深度为k的二叉树最多有 2^(i) - 1 个节点
特别地,一颗深度为k且有2^k - 1 个节点的二叉树称为满二叉树;
完全二叉树是将满二叉树从最后一层的最后的节点,依次拿掉节点,
/*二叉树的二叉链表存储结构*/
typedef struct BitNode{
int data;
struct BitNode *lchild, *rchild;
}BitNode,*BiTree;
void PreOrder(BiTree p)
{
if(p!=NULL)
{
printf("%d",p->data); //访问根节点
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
void InOrder(BiTree p)
{
if(p!=NULL)
{
PreOrder(p->lchild);
printf("%d",p->data); //访问根节点
PreOrder(p->rchild);
}
}
void PostOrder(BiTree p)
{
if(p!=NULL)
{
printf("%d",p->data); //访问根节点
PreOrder(p->rchild);
PreOrder(p->lchild);
}
}
当结点的左指针为空时(即无左子树),令该指针指向按某种方式遍历二叉树时该结点的驱结点;
当结点的右指针为空时,令该指针指向按某种遍历二叉树时该结点的后继结点。为了避免混淆,
可定义这种指向结点的前驱或后继的指针信息为线索
/**********二叉树的二叉线索存储表示***************************/
typedef struct BiThrNode
{
ElemType data;
struct BiThrNode *lchild ,*rchild; /*左右指针*/
int ltag,rtag; /*左右指针类型标志,0表示指针,1表示线索*/
}
哈夫曼树是一种带权路径长度最小的树
树的路径长度是从树根到每一个结点的路径长度之和.
树的带权路径长度: 从树根结点到该结点之间的路径长度与该结点上权的乘积之和
WPL=wi*lI+...+...;
分支结点不带权值,只有叶子结点才带权值,权值越大的结点离树根越近,则二叉树的带权路径长度就越小