zoukankan      html  css  js  c++  java
  • 数据结构(三) 树和二叉树,以及Huffman树

    三、树和二叉树

      1、树

      2、二叉树

      3、遍历二叉树和线索二叉树

      4、赫夫曼树及应用

     树和二叉树

             树状结构是一种常用的非线性结构,元素之间有分支和层次关系,除了树根元素无前驱外,其它元素都有唯一前驱。

             非空树中节点特征:

      (1)只有一个根节点,它只有直接后继,但没有直接前驱;

      (2)元素个数n>1时,其余节点可分为m个互不相交的有限集合。每一个集合本身又是一棵树,称为根的子树。子树的根节点只有一个直接前驱,可以有任意个直接后继。

    基本术语

      结点:包含数据元素以及逻辑关系信息。

      结点的度:节点拥有的子树数目(0,1,2)。

      树的度:树中所有结点点的度的最大值。

      叶子节点:度为0的结点。

      分支结点:度大于0的结点。即除叶子结点外的其它结点。

      孩子结点:若结点有子树,则子树的根结点称为这个节点的孩子节点。

      双亲结点:反过来,此结点称为孩子结点的双亲结点。叶子结点没有孩子。

      结点的层次:依次加一。根结点的层次为1~

      树的高度:叶子结点所在的最大层次为树的高度,也可以称为树的深度。空树高度为0。

      兄弟结点:同一双亲的孩子结点之间互称兄弟。

      堂兄弟节点:同一层次,双亲不同的结点。

      祖先节点&子孙节点:如名字所说。

      路径:从树的一个结点到另一个结点的分支构成这两个结点之间的路径。

      有序树:如果将节点的各棵子树看成从左至右是有次序的,即子树之间存在确定的次序关系,则称该树为有序树。

      无序树:根结点的各棵子树之间不存在确定的次序关系,可以互相交换位置。

      森林:m棵不相交的树的集合构成森林。M>=0。    

     

    二叉树

             二叉树是一种适合计算机处理的特殊的树,其每个结点至多只有两棵子树,并且二叉树的两棵子树有左右之分。

    任何树和森林都可以转换为二叉树!!

      二叉树的性质:

      (1) 二叉树的第i层最多有2^(i-1)个结点;

      (2) 高度为k的二叉树上至多有(2^k)-1个结点;

      (3) 任意一棵二叉树,若它含有n个叶子节点,m个度为2的结点,则有n=m+1;

      引申:

      满二叉树:只含有度为0和2的结点,且度为0的结点只出现在最后一层。

      完全二叉树:对任意一棵满二叉树,从它最后一层的最右结点起,按从下到上、从右到左的次序,去掉若干个结点后,得到的二叉树。

      (4) 具有n个结点的完全二叉树的高度为[log(2)n]+1;

      (5) 若对含有n个结点的完全二叉树,按照从上到下,从左至右的次序进行1至n的编号,对完全二叉树中任意一个编号为i的结点,简称为结点i,有以下关系:

      A. i=1,结点i是二叉树的根,无双亲;若i>1,结点[i/2](向下取整)为双亲结点;

      B.  若2i>n,则结点i无左x孩子,否则结点2i为左孩子;

      C.  若2i+1>n,则结点i无右孩子,否则结点2i+1为右孩子。

      二叉树的存储结构:-

      1、  顺序存储结构

      按照结点的层次从上到下、从左至右,将完全二叉树结点存储在一片连续存储区域内。存储只保留结点的值。这样的方式,对于完全二叉树来说,非常方便,因为已知结点的编号就可以推算出它的双亲和孩子结点的编号,因此是一种很经济的存储方式。

      但是,对于一般而二叉树来说,需要补设一些虚结点。这样可能会造成很大的空间浪费。因此,一般情况下,很少使用顺序存储方式。

      2、  链式存储结构。

      链表的结点中至少包含:左孩子指针、数据元素、右孩子指针。这是二叉链表,从根结点出发可以访问到所有结点。缺点是,从某个节点出发,寻找双亲结点时,需要从根节点开始搜索,效率极低!

      为解决这个问题,可以在结点中增加一个指向双亲结点的指针,即三叉链表结构。

      实际使用中,一般还是使用二叉链表。

    二叉树遍历

             若规定先左后右的顺序,则只存在:DLR先序遍历、LDR中序遍历、LRD后序遍历、层次遍历。命名根据根节点被遍历的次序。

      1、  先序遍历:根—左子树—右子树

      2、  中序遍历:左子树—根—右子树

      3、  后序遍历:左子树—右子树—根  

      遍历算法:递归算法很简单,非递归要复杂许多。·

             遍历应用:

      1、  计算结点个数与树的高度

      2、  二叉树的销毁

      3、  二叉树的复制

      4、  二叉树的显示:可按中序遍历的算法编程实现。

      5、  由先序序列与中序序列构造二叉树

      仅仅由二叉树的先根遍历序列不能唯一确定一棵二叉树,需要在先根序列中加入空子树的信息;

      根据一棵树的先序遍历和中序遍历,或者后序遍历和中序遍历序列,都可以唯一地确定一棵树。

     

      6、  表达式的前缀表示、中缀表示和后缀表示

     

                                                                               线索二叉树

             按某种方式遍历二叉树,遍历所得到结果序列就变为线性结构,树中所有结点都按照某种次序排列在一个线性有序的序列中,每个结点就有了唯一的前驱和后继。

             而当以二叉链表为存储结构时,只能找到结点左、右孩子信息,而不能直接得到前驱和孩子信息。高效经济的方法是利用空指针成员存放结点在某种遍历次序下的前驱或者后继指针。

    哈夫曼树与哈夫曼编码

             Huffman树也称最优树,是一类带权路径长度最短的树,在实际中有广泛的用途。

             路径:从树的一个结点到另一个结点的分支构成这两个结点之间的路径,对于huffman树,特指从根结点到某结点的路径。

             路径长度:路径上的分支数叫做路径长度。

             树的路径长度:从树根到每一个结点的路径长度之和。

             权:赋予某个事物一个量,对其属性进行数值化描述。数据结构中有结点权和边权。

             结点的带权路径长度:从树根到结点之间的路径长度与结点上权的乘积。

             树的带权路径长度:简称WPL,树中所有叶子结点的带权路径长度之和。

             哈夫曼树:根据给定的n个值w1、w2、…、wn,可以构造出多棵具有n个叶子结点且其权值分别为这n个给定值的二叉树,其中带权路径长度WPL最小的二叉树叫做最优树。

             在哈夫曼树中,权值越大的结点离根节点越近。

             哈夫曼算法:

             由n个权值构造n个带权结点—选其中权值最小的两个结点构造一棵新树,它们分别为左右孩子—删除这两个结点,把新树放入森林中—重复前面步骤直到只有一棵树。

            

    Huffman编码

      思考:在已知传输的字符集合及其出现频度的情况下,是否可得到更有效的编码使得传输的编码长度达到最短呢?

      为了缩短编码总长度,可采用不定长编码。

      前缀码:一个编码系统中,任一个编码都不是其他任何编码的前缀,则称此编码系统中的编码是前缀码。

      哈夫曼编码就是利用哈夫曼树来设计的最优前缀编码,也就是报文编码总长度最短的二进制前缀编码。利用n个字符的频率作为权值,设计一棵哈夫曼树。然后左分支赋值0,右分支赋值1。从根到每个叶子的路径上,各分支的赋值分别构成一个二进制串。该二进制串即为对应字符的前缀编码。

      具有n个字符的报文的总编码长度就是哈夫曼树的带权路径长度,所以得到的不定长编码就是最优前缀编码。

      解码方法:根据哈夫曼树来走就行了。去一个码走一步,如果走到叶子节点就译码。

                                                                                                                                         

  • 相关阅读:
    Python if __name__ == "__main__" 的含义
    自己用
    phpstorm && pycharm
    API Design for C++ 一本书值得一看
    std::set 使用
    Using Windows Web Services
    SOA 好好了解下
    NI Measurement Studio Enterprise 8.6
    那天看看
    内存映射 那天自己改改
  • 原文地址:https://www.cnblogs.com/bigbigbigo/p/8616868.html
Copyright © 2011-2022 走看看