zoukankan      html  css  js  c++  java
  • 6.3 树和森林


    title: 数据结构 | 树-3 | 树和森林
    date: 2019-12-03 13:03:55
    tags: 数据结构


    数的存储结构(表示法)、森林与二叉树的转换、
    树和森林的遍历、哈夫曼树

    树的存储结构

    双亲表示法

    取一块连续的内存空间,在存储每个结点的同时,各自都附加一个记录其双亲结点位置的变量。
    双亲表示法

    • 代码实现
    typedef struct PTNode  //结点结构
    {
        ElemType data;
        int parent;//结点的父结点在数组中的位置下标
    }PTNode;
    

    孩子表示法

    将树中的每个结点的孩子结点排列成一个线性表,用链表存储起来。对于含有 n 个结点的树来说,就会有 n 个单链表,再把 n 个单链表的头指针存储在一个线性表中。如果结点没有孩子,则其单链表为空。
    孩子表示法

    • 代码表示
    typedef struct CTNode//每个节点的孩子链表
    {
      int child;  //数据在数组中存储的位置下标
      struct CTNode *next;
    }*ChildPtr;
    
    typedef struct //每个节点的信息
    {
      TElemType data;  
      ChildPtr firstchild;  //孩子链表的头指针
    }CTBox;
    
    typedef struct//全树
    {
      CTBox nodes[Tree_Size];  //存储结点的数组
      int n, r;  //结点数量和树根的位置
    }CTree;
    

    孩子兄弟表示法(二叉树表示法)

    孩子兄弟表示法

    • 代码表示
    typedef struct CSNode
    {
      ElemType data;
      struct CSNode *firstchild, *nextsibling;
    }CSNode, *CSTree;
    

    通过孩子兄弟表示法,普通树转化为了二叉树,所以孩子兄弟表示法又被称为“二叉树表示法”或者“二叉链表表示法”。

    森林与二叉树转换

    将树转换成二叉树

    加线:在兄弟之间加一连线
    抹线:对每个结点,除了其左孩子外,去除其与其余孩子之间的关系
    旋转:以树的根结点为轴心,将整树顺时针转45°

    将二叉树转换成树

    加线:若p结点是双亲结点的左孩子,则将p的右孩子,右孩子的右孩子,……沿分支找到的所有右孩子,都与p的双亲用线连起来
    抹线:抹掉原二叉树中双亲与右孩子之间的连线
    调整:将结点按层次排列,形成树结构

    森林转换成二叉树

    将各棵树分别转换成二叉树
    将每棵树的根结点用线相连
    以第一棵树根结点为二叉树的根,再以根结点为轴心,顺时针旋转,构成二叉树型结构

    二叉树转换成森林

    抹线:将二叉树中根结点与其右孩子连线,及沿右分支搜索到的所有右孩子间连线全部抹掉,使之变成孤立的二叉树
    还原:将孤立的二叉树还原成树

    树和森林的遍历

    树的遍历

    遍历

    按一定规律走遍树的各个顶点,且使每一顶点仅被访问一次,即找一个完整而有规律的走法,以得到树中所有结点的一个线性排列

    常用方法

    • 先根(序)遍历:
      先访问树的根结点,然后依次先根遍历根的每棵子树
    • 后根(序)遍历:
      先依次后根遍历每棵子树,然后访问根结点
    • 按层次遍历:
      先访问第一层上的结点,然后依次遍历第二层,……第n层的结点

    森林遍历

    • 先序遍历森林
      若森林非空:
      访问森林中第一棵树的根结点;先序遍历第一棵树根结点的子树森林;
      先序遍历除第一棵树后剩余的树构成的森林;
    • 中序遍历森林
      若森林非空:
      中序遍历第一棵树根结点的子树森林;访问第一棵树的根结点;
      中序遍历除第一棵树后剩余的树构成的森林;

    哈夫曼树(Huffman)

    带权路径长度最短的树

    基本概念

    • 路径:从树中一个结点到另一个结点之间的分支构成这
      两个结点间的~
    • 路径长度:路径上的分支数目
    • 树的路径长度:从树根到每一个结点的路径长度之和
    • 树的带权路径长度:树中所有带权叶子结点的路径长度之和

    Huffman树

    设有n个权值{w1,w2,……wn},构造一棵有n个叶子结点的二叉树,每个叶子的权值为wi,则wpl最小的二叉树叫Huffman树

    Huffman算法

    • 构造Huffman树步骤
      》根据给定的n个权值{w1,w2,……wn},构造n棵只有根结点的二叉树,令其权值为wj。
      》在森林中选取两棵根结点权值最小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和。
      》在森林中删除这两棵树,同时将新得到的二叉树加入森林中。
      》重复上述两步,直到只含一棵树为止,这棵树即哈夫曼树。

    Huffman编码

    哈弗曼编码是数据通信用的二进制编码

    • 思想:根据字符出现频率编码,使电文总长最短
    • 编码:根据字符出现频率构造Huffman树,然后将树中结点引向其左孩子的分支标“0”,引向其右孩子的分支标“1”(左0右1);每个字符的编码即为从根到每个叶子的路径上得到的0、1序列
  • 相关阅读:
    centos 用户管理
    rsync 实验
    文件共享和传输
    PAT 1109 Group Photo
    PAT 1108 Finding Average
    PAT 1107 Social Clusters
    PAT 1106 Lowest Price in Supply Chain
    PAT 1105 Spiral Matrix
    PAT 1104 Sum of Number Segments
    PAT 1103 Integer Factorization
  • 原文地址:https://www.cnblogs.com/nightland/p/13504396.html
Copyright © 2011-2022 走看看