树是n个结点的有限集。n = 0时称为空树。在任何一棵非空树中:
(1)有且仅有一个特定的称为根(Root)的结点;
(2)当n > 1时,其余节点可分为位数个互不相交的有限集,其中每一个集合本身又是一棵树,并且称为根的子树。
树的结点包含一个数据元素及若干指向其子树的分支。结点拥有的子树树称为结点的度。度为0的结点称为叶结点或终端结点;度不为0的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。树的度是树内各节点的度的最大值。
结点的子树的根称为该结点的孩子,相应的,该结点成为孩子的双亲。同一个双亲的孩子之间互称兄弟。结点的祖先是从跟到该结点所经分支上的所有结点。以根结点为根的子树中的任意结点都称为该结点的子孙。
结点的层次从根定义起,根为第一层,根的孩子为第二层。双亲在同一层的结点互为堂兄弟。树中结点的最大层次称为树的深度或高度。
如果将树中结点的各子树看成从左至右是有次序的,不能交换的,则称该树为有序树,否则称为无序树。
森林是m棵不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。
线性结构和树结构的区别
第一个数据元素 无前驱;根结点 无双亲 唯一。
最后一个数据元素 无后继;叶结点 无孩子 可以多个。
中间元素 一个前驱 一个后继;中间结点 一个双亲 多个孩子。
存储结构的设计是一个非常灵活的过程,一个存储结构设计得是否合理,取决于基于该存储结构的运算是否适合、是否方便,时间复杂度等。
树的存储结构
1.双亲表示法
每个结点中,附设一个指示器指示其双亲结点到链表中的位置。每个结点有一个域存储最左边孩子 可称为长子域。再使用一个右兄弟域存储兄弟的下标。
2.孩子表示法
每个结点有多个指针域,其中每个指针指向一颗子树的根结点,我们把这种方法叫做多重链表表示法。
把每个结点的孩子结点排列起来,以单链表作存储结构,则n个结点由n个孩子链表,如果是叶子节点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中。
3.孩子兄弟表示法
任何一棵树,它的结点第一个孩子如果存在就是唯一,它的有兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。
二叉树是n个结点的有限集合,该集合或者为空集(空二叉树),或者有一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
二叉树的特点:
1.每个结点最多有两棵子树。
2.左子树和右子树有顺序的,次序不能任意颠倒。
3.即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。
特殊的二叉树:
左|右斜树:所有的结点都只有左|右子树的二叉树叫左|右斜树。
满二叉树:在一棵二叉树中,所有的分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
完全二叉树:对一棵具有n个结点的二叉树按层序编号,如果编号为i的结点与同样深度的满二叉树编号为i的结点在二叉树中位置完全相同。
满二叉树一定是完全二叉树。
完全二叉树的特点:
1.叶子结点只能出现在最下两层。
2.最下层的叶子一定集中在左部连续位置。
3.倒数二层,若有叶子结点,一定都在右部连续位置。
4.如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况。
5.同样节点数的二叉树,完全二叉树的深度最小。
二叉树的性质:
1.在二叉树的第i层上至多有2i-1个结点。
2.深度为k的二叉树之多有2k-1个结点。
3.对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点树为n2,则n0=n2+1。
4.具有n个结点的完全二叉树的深度为(Log2n) + 1。
5.如果对一棵有n个结点的完全二叉树的结点按层序编号,对任意结点i有:
1.如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点。
2.如果2i>n,则结点i无左孩子,否则其左孩子是结点2i。
3.如果2i+1>n,则结点i无有孩子;否则其有孩子是结点2i+1。
树的顺序存储结构:
把结点按照深度,从左到右依次排序,空则记为^。通常只适用于完全二叉树。
二叉链表:二叉树每个结点最多有两个孩子,所以设计一个数据域和两个指针域。
二叉树的遍历:从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
前序遍历:从根结点开始,前序遍历左子树,再前序遍历右子树。
中序遍历:从叶结点开始,先遍历该侧子树,再从另一侧子树叶结点开始遍历。
后序遍历,从左到右,先叶子后结点的遍历左右子树最后访问根结点。
层序遍历:规则是从树的第一层,即根结点开始访问,从上而下,从左而右的逐层遍历。
指向前驱和后继的指针叫做线索,加上线索的二叉树链表称为线索链表,相应的二叉树就成为线索二叉树。
二叉树以某种次序遍历使其变为线索二叉树的过程称作是线索化。
树转化为二叉树:
1.给所有兄弟结点之间架一条连线。
2.对树中每个结点,只保存他与第一个孩子结点的连线,删除与其他孩子的连线。
3.调整层次。
二叉树转化为树:
1.若某结点的做孩子结点存在,则将这个做孩子的右孩子结点、一直到做孩子的第n个右孩子结点都作为此结点的孩子。连线。
2.删除原二叉树中所有结点与其有孩子结点的连线。
3.调整层次。
赫夫曼树:从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目叫做路径长度。树的路径长度就是从树根到每一结点的路径长度之和。其中带权路径长度WPL最小的二叉树叫做赫夫曼树。
若要设计长短不等的编码,则必须是任意字符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码。
一半的,设需要编码的字符即为d1,d2....dn,各个字符在电文中出现的次数或频率集合为w1,w2...wn,以d1,d2....dn作为叶子结点,以w1,w2...wn作为相应叶子节点的全职来构造一棵赫夫曼树。规定赫夫曼树的左分支代表0,右分支代表1,则从根结点到叶子结点所经过的路径分支组成的0和1的序列变为该节点对应字符的编码,这就是赫夫曼编码。