欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《数据结构复习》树

程序员文章站 2024-01-16 22:51:04
...

复习概要:

  • 了解树的概念和基本术语
  • 掌握二叉树的概念,性质,分类
  • 掌握二叉树的存储结构和遍历方式
  • 熟悉二叉树的创建
  • 了解线索二叉树与哈夫曼数

1,树

1.1 什么是树

    树是由n个结点组成的一个具有层次关系的有限集合。

    树中相关的概念:根,结点,叶子,孩子结点,兄弟节点,祖先结点,度,树的高度。

1.2 树的表示法

    1,图形表示法

    图像表示法就是通常看到的由圈圈和线组成的数。

    2,广义表表示法

    如: (A(B(E,F,G),C(H),D(I,J)))

    3,左孩子右兄弟表示法

    结点的左边是节点的子结点,右边是节点的兄弟节点,   通常使用这种方法将树转化为二叉树

2,二叉树

2.1 什么是二叉树

    二叉树具有两个基本的特征如下:

  • 每个节点最多只能有两个孩子结点
  • 二叉树是有序树,左子树和右子树次序不能颠倒,即使树中某个节点只有一颗子树,也要区分是左子树还是右子树。
2.2 二叉树的分类

    根据二叉树中子节点的排布,可将二叉树分为非完全二叉树,完全二叉树和满二叉树。

2.3 二叉树的性质

  1. 在二叉树的第i层上至多有2^(i-1)个结点
  2. 深度为k的二叉树至多有2^k -1个结点
  3. 对于任何一颗二叉树,若度为2的结点数有n2个,则叶子节点数必定为n2+1个
  4. 具有n个节点的完全二叉树,它的深度必为[log2 n]+1
  5. 若对于完全二叉树中的节点从上至下,从左至右编号,则编号为i(1<=i<=n)的节点,其左孩子编号必为2i,其右孩子节点必为2i+1,其双亲编号必为i/2

3,二叉树的存储结构

3.1 二叉树的顺序存储

    对于完全二叉树的顺序存储,可以根据角标推算出节点在二叉树中的位置。

    对于一般二叉树的顺序存储,依据角标并不能推算出节点在二叉树中的位置,所以对于一般二叉树,存储方式是补全二叉树的顺序存储。

    对于二叉树的顺序存储...  额 实际中并不会这样存储,因为太麻烦了,了解一下就好

3.2 二叉树的链式存储

1,二叉树链表示法

    使用二叉链表示树,通常树中的每个节点由三部分组成:数据域和左,右指针域。

    结点的类型定义如下:

typedef struct BitNode
{
	DataType data;
	struct BitNode *lchild,*rchild;
}BitNode;
typedef struct BitNode *BiTree;

2,三叉链表示法

    使用三叉链表示法,树中的每个节点教二叉链表示法多了父节点的指针,

    节点的类型定义如下:

typedef struct BitNode
{
	DataType data;
	struct BitNode *lchild,*rchild;
        struct BitNode *parent;
}BitNode;
typedef struct BitNode *BiTree;

4,二叉树的遍历

    遍历一颗二叉树有很多种方法。加入用D,L,R分别表示二叉树的根节点,左子树,右子树,那么要遍历这颗二叉树,方法就有6种:DLR,DRL,LDR,LRD,RDL,RLD。一般在遍历时遵循先左后有的原则,因此常用的遍历方法有三种:DLR。称为先序(根)遍历,LDR,称为中序(根)遍历。LRD,称为后序(根)遍历。

4.1 二叉树的遍历

    如下图所示的一颗二叉树,该二叉树的先序遍历为ABFLDI,中序遍历为BLFAID,后序遍历为LFBIDA

《数据结构复习》树

5,二叉树与树,森林之间的转换

5.1 二叉树与树之间的转换

    二叉树与树之间的转换实际上是将树转换成左孩子右兄弟二叉树。

5.2 二叉树与森林之间的转换

    1,森林转换为二叉树

    2,二叉树转换成森林

    以上两个实质上都是左孩子右兄弟二叉树和 树或森林之间的转换

6,二叉树的创建

    在前面的复习中,二叉树都是静态创建的,但是这实际开发中,二叉树往往是动态创建的。常用的动态创建二叉树的方法有中序先序法和#号法。

6.1  中序和先序创建二叉树

    创建一颗二叉树的方法有如下两种:

  • 中序遍历结果和先序遍历结果一起可以确定一颗二叉树
  • 终须遍历结果和后序遍历结果一起可以确定一颗二叉树

注意:即使结合先序遍历和后序遍历的结果也无法确定一颗二叉树的结构。因为这两种遍历结果结合只能求解出根,不能确定左子树什么时候结束,右子树什么时候开始。

    根据中序遍历和先序遍历的结果确定二叉树的基本思路如下:

    在谈论基本思路先,先思考二叉树的中序遍历和先序遍历结果中根节点和左子树,右子树的特征:

    在先序遍历中,先遍历根节点,然后遍历左子树,再遍历右子树

    在中序遍历中,先遍历左子树,再遍历根结点,再遍历右子树。

    所以如上描述的一样,先序遍历的特征是(根节点(左子树的根节点+左子树的子节点)(右子树的根结点+右子树的其他接待你))。中序遍历的特征是(左子树,根节点,右子树)

    故一般思路为

  • 通过先序遍历找到根节点,在通过根接单在中序遍历的位置找到左子树,右子树
  • 根据左子树在先序遍历结果的顺序,找到左子树的根节点,视左子树为一颗独立的树,转第一个步骤
  • 根据右子树在先序遍历结果的孙旭,找到右子树的根节点,视右子树为一颗独立的树,转第一个步骤
6.2 #号法创建树

    单独使用先序遍历结果无法唯一确定一颗二叉树,但如果用#号法,先序遍历结果就可以唯一确定一颗二叉树。

    #号法是让每一颗树都变成度数为2的树,度不为2的节点就用#符号补全。

    看个例子:如DFE###B## 

7 线索二叉树

7.1 什么是线索二叉树

    把执行前驱和后继的指针称为线索,带有线索的二叉链表称为线索链表,带有线索的二叉树称为线索二叉树。

线索二叉树的结点结构定义

typedef struct BitNode
{
	DataType data;
	struct BitNode *lchild,*rchild;
	int LTag;
	int RTag;
}BitNode,*Bithrtree;
typedef struct BitNode *BiTree;
7.2 二叉树的线索化

    将二叉树变为线索二叉树的过程称为线索化。按某种次序将二叉树线索化的实质是:按该次序遍历二叉树,在遍历的过程中用线索取代空指针。按照遍历方式,线索化也可分为先序线索化,中序线索化和后序线索化。其中先序线索化瘀后序线索化要比中序线索化稍难

8 赫夫曼树

8.1 什么是赫夫曼树

    在了解赫夫曼树之前,先了解几个术语:

  • 路径:它是指从某一节点到另一个节点的线路
  • 树的路径长度:是从树根到树中每一个结点的路径长度之和。
  • 树的带权路径:节点到树根之间的路径长度与该结点上权值的乘积之和

    赫夫曼树是以一种树的带权路径最短的二叉树

8.2 赫夫曼树的构造
8.3 赫夫曼编码