@defias
2016-04-12T11:20:49.000000Z
字数 3844
阅读 1925
算法与数据结构
树(Tree)的定义:n(n~0)个结点的有限集,n=0时称为空树,在任意一棵非空树中:
n=0:空树
n>0:非空树 根结点是唯一的,不可能存在多个根结点
含子树时: 子树的个数没有限制,但它们一定是互不相交的
不是树:
树的结点:包含一个数据元素及若干指向其子树的分支
结点的度:结点拥有的子树数称为结点的度 (Degree)
树的度:是树内各结点的度的最大值
孩子:结点的子树的根称为该结点的孩子(Child)
双亲:该结点称为孩子的双亲(Parent)
兄弟:同一个双亲的孩子之间互称兄弟 (Sibling)
祖先:结点的祖先是从根到该结点所经分支上的所有结点
子孙:以某结点为根的子树中的任一结点都称为该结点的子孙
结点的层次(Level):从根开始定义起,根为第一层,根的孩子为第二层,若某结点在第n层,则其子树的根就在第n+1层
堂兄弟: 其双亲在同一层的结点互为堂兄弟
树的深度:树中结点的最大层次称为树的深度(Depth)或高度
有序树:如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树为有序树
无序树:否则称为无序树
森林(Forest): m(m>=0)棵互不相交的树的集合。对树中每个结点而 ,其子树的集合即为森林
树的存储结构:
(顺序存储结构不能满足树的实现要求)
二叉树(Bina Tree)的定义:n(n>=O)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成
二叉树特点:
五种基本形态:
左斜树:所有的结点都只有左子树的二叉树叫左斜树
右斜树:所有结点都是只有右子树的二叉树叫右斜树
斜树:这两者统称为斜树
满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层,这样的二叉树称为满二叉树
满二叉树的特点:
完全二叉树:对一棵具有n个结点的二叉树按层序编号,如果编号为i(1<=i<=n) 的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树
完全二叉树的特点:
非完全二叉树:
二叉树的性质:
二叉树的遍历:
(trave ing bina tree)是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次
二叉树的遍历方法:
- 前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子再前序遍历右子树
线索二叉树:利用空地址存放指向结点在某种遍历次序下的前驱和后继结点的地址,这种指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树就称为线索二叉树(Threaded Binary Tree)
线索化:对二叉树以某种次序遍历使其变为线索二叉树的过程称做是线索化。线索化的实质就是将二叉链表中的空指针改为指向前驱或后继的线索。由于前驱和后继的信息只有在遍历该叉树时才能得到,所以线索化的过程就是在遍历的过程中修改空指针的过程
如果所用的二叉树需经常遍历或查找结点时需要某种遍历序列中的前驱和后继,那么采用线索二叉链表的存储结构就是非常不错的选择
树转换为二叉树的步骤:
森林转换为二叉树的步骤:
(森林是由若干棵树组成的,所以完全可以理解为,森林中的每一棵树都是兄弟,可以按照兄弟的处理办法来操作)
二叉树转换为树的步骤:
(二叉树转换为树是树转换为 叉树的逆过程,也就是反过来做而已)
二叉树转换为森林的步骤:
(判断一棵二叉树能够转换成一棵树还是森林,只要看这棵二叉树的根结点有没有右孩子,有就是森林,没有就是一棵树)
树的遍历:分为两种方式:
森林的遍历:也分为两种方式:
路径长度:从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称做路径长度,树的路径长度就是从树根到每一结点的路径长度之和
带权路径长度:结点的带权的路径长度为从该结点到树根之间的路径长度与结点上权的乘积;树的带权路径长度为树中所有叶子结点的带权路径长度之和
赫夫曼树:假设有n个权值{w1, w2, ...wn},构造一棵有n个叶子结点的二叉树,每个叶子结点带权wk,每个叶子的路径长度为lk,则其中带权路径长度WPL最小的二叉树称做赫夫曼树树(最优二叉树)
构造赫夫曼树的赫夫曼算法:
赫夫曼编码:
设需要编码的字符集为{d1, d2, ...dn},各个字符在电文中出现的次数或频率集合为{w1, w2, ...wn},以d1,d2,...dn作为叶子结点,以w1, w2, ...wn作为相应叶子结点的权值来构造一棵赫夫曼树,规定赫夫曼树的左分支代表0,右分支代表1,则从根结点到叶子结点所经过的路径分支组成的0和1的序列便为该结点对应字符的编码,这就是赫夫曼编码