第六章 树【数据结构和算法】2

简介: 第六章 树【数据结构和算法】2

6.5线索二叉树

6.5.1 线索二叉树的基本概念

在线索二叉树中,为了正确区分指向左右孩子的指针和指向前驱后驱的指针,将结点结构改为5个域,原二又链表中的左孩子域、数据域和右孩子域依战保持不变,增加左标志域Ltag和右标志域它们是两个布尔型的数据城。

线索二叉树的结点结构如下 :

LChild Ltag Data Rtarg RChild


①若结点有左子树,则LChild城仍指向其左孩子;否则,LChild域指向其遍历序列中的直接前驱结点

②若结点有右子树,则RChild域仍指向其右孩子;否则,RChild域指向其遍历序列中的直接后继结点

③ Lag和Rtag的定义如下:

    {   0 LChild域指示结点的左孩子
Ltag =  {
    { 1 LChild域指示结点的遍历前驱
    { 0 RChild域指示结点的右孩子
Rtag =  {
    { 1 RChid域指示结点的遍历后继

在上述存储结构中,指向前驱和后继结点的指针称为“线索”,对二叉树以某种次序进行遍历并且将空指针改为线索的过程叫做“线索化”,经过线索化的一叉树称为“线索二叉树”;以上述结点结构存储的含有线索的二叉链表称为“线索链表”

依据二叉树遍历策略的不同,存在三种不同的线索二叉树。依据二叉树的先序、中序、后序 遍历策略,分别对应有先序线索二叉树、中序线索二叉树和后序线索二叉树。

6.5.2 二叉树的线索化

6.5.3 线索二叉树的遍历

6.6 树和森林

6.6.1 树的存储

1.双亲表示法

双亲表示法的存储结构定义如下。

define MAX 100
typedef struct TNode{  /*顺序表结点结构定义。/  
  DataType data;
  int parent;
}TNode;
typedef struct{     /*树的定义*/
  TNode tree[MAX];
  int root;     /*树的根结点在表中的位置*/
  int num;      /*树的结点个数*/
 }PTree;

2.孩子表示法

孩子表示法的存储结构定义如下。

typedef struct ChildNode{ //孩子链表结点结构定义
  int Child;
  Struct ChildNode * next;
}ChildNode;
typedef struct{       //顺序表结点结构定义
  DataType data;
  ChildNode w FirstChild;
| DataNode;
typedef struct{       //树的定义
  DataNode nodes[ MAX];
  int root;       //树的根结点在顺序表中的位置
  int num;        //树的结点个数
| CTree;

3.孩子兄弟表示法

孩子兄弟表示法的存储结构定义如下。

typedef struet CSNode{
  DataType data;          /*结点信息*/
  Struct CSNode * FirstChild;   /*第一个孩子指针*/
  Struct CSNode * NextSibling;  /*右兄弟指针*/
}CSNode.* CSTree;

6.6.2 树、森林与二叉树的转换

6.6.3 树和森林的遍历

二叉树 森林
先序 先根 先序
中序 后根 中序
中序 \ 中序

6.7哈夫曼树及其应用

哈夫曼(Hufman)树,又称最优二叉树,是带权路径长度最短的树,来构造最优编码,用于信息传输、数据压缩等方面,是一种应用广泛的二叉树。

6.7.1哈夫曼树

在介绍哈夫量树之前,先介绍几个与哈夫曼树相关的基本概念
路径;树中个结点到另一个结点之间的分支序列构成两个结点间的路径,

路径长度:路径上分支的条数称为“路径长度”。

树的路径长度:从树根到每个结点的路径长度之和称为“树的路径长度”。
6.3节介绍的完全二叉树,是结点数给定的情况下路径长度最短的二叉树。

带权路径长度:结点到树根间的路径长度与结点的权的乘积,称为该结点的“带机

结点的权:给树中结点赋予一个数值,该数值称为“结点的权”。

树的带权路径长度:树中所有叶子结点的带权路径长度之和,称为“树的带权路径长度",常记为WPL:

WPL = ∑nk=1 Wkx,Lk


其中,n为叶子数,Wk为第k个叶子的权值,Lk为第k个叶子到树根的路径长度。

最优二叉树:在叶子个数n以及各叶子的权值W,确定的条件下,树的带权路径长度W 最小的二叉树称为“最优二叉树”。

1.哈夫曼树的建立

2.哈夫曼算法的实现

相关代码请看配套资源

int main(){
  HuffmanTree ht;
  int w[6]={0,5,7,3,2,8};
  int n=5;
  CrHuffmanTree(ht,w,n);
  int m=2*n-1;
  int i;
  printf("输出哈夫曼树\n");
  for (i=1;i<=m;i++){
    printf("%d %d %d %d\n",ht[i].Weight,ht[i].Parent,ht[i].Lchild,ht[i].Rchild); 
  } 
  HuffmanCode hc;
  CrtHuffmanCode1(ht,hc,n);
  printf("输出哈夫曼编码\n");
  for (i=1;i<=n;i++){
    printf("%d:",ht[i].Weight);
    char * cd=hc[i];
    puts(cd);
  }
  /*
  5--01
  7--10
  3--001
  2--000
  8--11
  */
  char str[13]={'0','1','1','0','0','0','1','0','0','0','1','1'};
  printf("输出译码\n");
  decondind(ht,str,n);
}

运行结果如下



6.7.2哈夫曼编译码

1.哈夫曼编码的概念

信息压缩达到最短的前缀编码

2.哈夫曼编码的算法实现

相关代码请看配套资源

运行结果如下



3.哈夫曼编码的译码

相关代码请看配套资源

运行结果如下


数据结构C 语言哈夫曼编译码基本实现 haffman.c 完整代码中有

6.8 实例分析与实现

6.8.1表达式树

6.8.2树与等价类的划分

6.8.3回溯法与N皇后问题

上机实验【数据结构】

第六章 上机实验【数据结构】

6.9 算法总结

习题

1.单项选择题

(1)树最适合用来表示的结构是B
A.元素间的有序结构

B.元素间具有分支及层次关系的结构

C.元素间的无序结构

D.元素间无联系的结构

(2)设一棵二叉树的结点个数为18,则它的高度至少为B
A.4

B.5

C.6

D.18

(3)任意一棵二叉树的叶子结点在其先序、中序、后序序列中的相对位置C
A.肯定发生变化

B.有时发生变化

C.肯定不发生变化

D.无法确定

4)判断线索二叉树中某结点P有左孩子的条件是C
A. p!=NULL

B.p->lchild!=NULL

C.p->LTag=0

D.p->LTag=1

(5)二叉树在线索化后,仍不能有效求解的问题是C
A.先序线索二叉树中求后继

B.中序线索二叉树中求后继

C.中序线索二叉树中求前驱

D.后序线索二叉树中求后继

(6)设森林T中有4棵树,其结点个数分别为n、nz、ng、ng,那么当森林T转换成一棵二叉树后,则根结点 的右子树上有 D 个结点。
A.n1-1

B.n1

C.n1+n2+n3

D.n2+n3+n4

(7)由权值分别为925.7的4个叶子结点构造一棵哈夫曼树,则该树的带权路径长度WPL为C
A.23

B.37

C.44

D.46

(8)设T是一棵哈夫曼树,有8个叶结点,则树T的高度最高可以是C
A.4

B.6

C.8

D.10

3.完成题

3完成题

(1)已知一棵二叉树的后序序列为ABCDEFG,中序序列为ACBCEDF。试完成下列操作。

①画出该二叉树的树形图。

G(C(A,B),F(E(^,D),^))

②给出该二叉树的先序序列。

GCABFED

③画出该二叉树的顺序存储结构示意图。

0 1 2 3 4 5 6 ... 13 ...
  G C F A B E      D

(2)已知一棵树的双亲表示法如下所示,试完成下列操作。

①画出该树的树形图。

A----------------------------------
  B----------------------------------
    E----------------------------------
      K--------------------------
    F----------------------------------
      C--------------------------
      M--------------------------
  C--------------------------
    G--------------------------
      N--------------------------
    H--------------------------
      O--------------------------
  D--------------------------
    I--------------------------
    J--------------------------

②画出该树的孩子兄弟二叉链表存储结构示意图。

                  A
                 B           ^
      E                   C
  K        F             G                   D
  ^  ^    C   ^      N     H          I  ^
        ^   M         ^ ^  O   ^           ^ J
                    ^ ^         ^ ^

③画出对应二叉树的中序线索二叉树。

中序:KELMFBNGOHCIJDA

(3)假设某通信报文的字符集由A、B、C、D、E、F共6个字符组成,它们在报文中出现的次数分别为16、12、9、30、3、6。试构造一棵哈夫曼树,并完成如下操作。

        (76)
      30      (46)
          (18)   (28)
        (9) 9     12 16
               3 6

①计算哈夫曼树的带权路径长度。

177

②写出各叶子结点对应字符的哈夫曼编码。

A   B    C   D  E    F
111 110  101 0  1000 1001 

4.算法设计题

(1)编写算法,在以二叉链表存储的二叉树中,求度为2的结点的个数。

int Node2(BiTree T){
  if(!T){
    return 0;
  }else if(T->LChild&&T->RChild){
    return Node2(T->LChild)+Node2(T->RChild)+1;
  }else{
    return Node2(T->LChild)+Node2(T->RChild);
  }
} 

(2)编写算法,在以二叉链表存储的二叉树中,交换二叉树各结点的左右子树。

struct TreeNode* invertTree(struct TreeNode *root){
  struct TreeNode* temp=NULL;
  if(root==NULL){
    return NULL;
  }
  temp=root->left;
  root->left=root->right;
  root->right=temp;
  invertTree(root->left);
  invertTree(root->right);
  return root;
} 
相关文章
|
2月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
58 1
|
2月前
|
机器学习/深度学习 算法 数据挖掘
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
146 4
|
2月前
|
算法
数据结构之博弈树搜索(深度优先搜索)
本文介绍了使用深度优先搜索(DFS)算法在二叉树中执行遍历及构建链表的过程。首先定义了二叉树节点`TreeNode`和链表节点`ListNode`的结构体。通过递归函数`dfs`实现了二叉树的深度优先遍历,按预序(根、左、右)输出节点值。接着,通过`buildLinkedList`函数根据DFS遍历的顺序构建了一个单链表,展示了如何将树结构转换为线性结构。最后,讨论了此算法的优点,如实现简单和内存效率高,同时也指出了潜在的内存管理问题,并分析了算法的时间复杂度。
60 0
|
16天前
|
存储 运维 监控
探索局域网电脑监控软件:Python算法与数据结构的巧妙结合
在数字化时代,局域网电脑监控软件成为企业管理和IT运维的重要工具,确保数据安全和网络稳定。本文探讨其背后的关键技术——Python中的算法与数据结构,如字典用于高效存储设备信息,以及数据收集、异常检测和聚合算法提升监控效率。通过Python代码示例,展示了如何实现基本监控功能,帮助读者理解其工作原理并激发技术兴趣。
50 20
|
2月前
|
存储 算法 搜索推荐
Python 中数据结构和算法的关系
数据结构是算法的载体,算法是对数据结构的操作和运用。它们共同构成了计算机程序的核心,对于提高程序的质量和性能具有至关重要的作用
|
2月前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
2月前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
117 23
|
2月前
|
算法
数据结构之蜜蜂算法
蜜蜂算法是一种受蜜蜂觅食行为启发的优化算法,通过模拟蜜蜂的群体智能来解决优化问题。本文介绍了蜜蜂算法的基本原理、数据结构设计、核心代码实现及算法优缺点。算法通过迭代更新蜜蜂位置,逐步优化适应度,最终找到问题的最优解。代码实现了单链表结构,用于管理蜜蜂节点,并通过适应度计算、节点移动等操作实现算法的核心功能。蜜蜂算法具有全局寻优能力强、参数设置简单等优点,但也存在对初始化参数敏感、计算复杂度高等缺点。
64 20
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
75 5
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
68 1