C#数据结构与算法揭秘七

前面介绍了线性结构,线性结构中的数据元素是一对一的关系。本章和下一章介绍两种非常重要的非线性结构:树形结构和图状结构。树形结构是一对多的非线性结构,非常类似于自然界中的树,数据元素之间既有分支关系,又有层次关系。树形结构在现实世界中广泛存在,如家族的家谱(图一)、一个单位的行政机构组织(图二)等都可以用树形结构来形象地表示。

树形结构在计算机领域中也有着非常广泛的应用,如 Windows 操作系统中对磁盘文件的管理、编译程序中对源程序的语法结构的表示等都采用树形结构。在数据库系统中,树形结构也是数据的重要组织形式之一。树形结构多叉树和二叉树两种,多叉树的操作实现比较复杂,但多叉树可以转换为二叉树进行处理,所以,本章主要讨论二叉树。

windows资源管理器是一个最典型的树形结构。

一张自然中典型的二叉树。

第一个问题,什么是树。所谓的树(Tree)是 n(n≥0)个相同类型的数据元素的有限集合。树中的数据元素叫结点(Node)。n=0 的树称为空树(Empty Tree);对于 n>0 的任意非空树 T 有: 

(1)有且仅有一个特殊的结点称为树的根(Root)结点,根没有前驱结点; 如图所示。

(2)若n>1,则除根结点外,其余结点被分成了m(m>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合Ti(1≤i≤m)本身又是一棵树。树T1,T2,…,Tm
称为这棵树的子树(Subtree)。如图所示:

由树的定义可知,树的定义是递归的,用树来定义树。因此,二叉树的许多算法都使用了递归。 树的形式定义为:树(Tree)简记为 T,是一个二元组, T = (D, R) 其中:D 是结点的有限集合;  是结点之间关系的有限集合。

由上述两个特点可知,图 5.2所示的都不是树

树的术语很多,我们来一一进行介绍。

1、结点(Node):表示树中的数据元素,由数据项和数据元素之间的关系组成。在下图中,共有 7个结点。
2、结点的度(Degree of Node):结点所拥有的子树的个数,在下图中,孙子结点的度为 3。
3、树的度(Degree of Tree):树中各结点度的最大值。在下图中,树的度为3.
4、叶子结点(Leaf Node):度为 0 的结点,也叫终端结点。在下图中,子结点和孙子结点都是叶子结点。
5、 分支结点(Branch Node): 度不为 0 的结点, 也叫非终端结点或内部结点。在下图中,根结点和子结点是分支结点。

6、孩子(Child):结点子树的根。在下图中,子结点是根结点的孩子。 

7、双亲(Parent):结点的上层结点叫该结点的双亲。在下图中,子结点的双亲是根结点。
8、祖先(Ancestor):从根到该结点所经分支上的所有结点。在下图中,孙子结点的祖先是子节点和根节点。
9、子孙(Descendant):以某结点为根的子树中的任一结点。在下图中,除根结点之外的所有结点都是根结点的子孙。
10、兄弟(Brother):同一双亲的孩子。在下图中,子结点互为兄弟。
11、结点的层次(Level of Node):从根结点到树中某结点所经路径上的分支数称为该结点的层次。根结点的层次规定为 1,其余结点的层次等于其双亲结点的层次加 1。

12、堂兄弟(Sibling):同一层的双亲不同的结点。
13、树的深度(Depth of Tree):树中结点的最大层次数。在下图中,树的深度为 3。
14、无序树(Unordered Tree):树中任意一个结点的各孩子结点之间的次序构成无关紧要的树。通常树指无序树。
15、有序树(Ordered Tree):树中任意一个结点的各孩子结点有严格排列次序的树。二叉树是有序树,因为二叉树中每个孩子结点都确切定义为是该结点的左孩子结点还是右孩子结点。
16、森林(Forest):m(m≥0)棵树的集合。自然界中的树和森林的概念差别很大,但在数据结构中树和森林的概念差别很小。从定义可知,一棵树有根结点和m 个子树构成,若把树的根结点删除,则树变成了包含 m 棵树的森林。当然,根据定义,一棵树也可以称为森林

树的逻辑表示方法很多,这里只讲几种常见的表示方法。
1、直观表示法
它象日常生活中的树木一样。整个图就象一棵倒立的树,从根结点出发不断扩展,根结点在最上层,叶子结点在最下面,如上图所示。
2、凹入表示法
每个结点对应一个矩形,所有结点的矩形都右对齐,根结点用最长的矩形表示,同一层的结点的矩形长度相同,层次越高,矩形长度越短,上图中的树的凹入表示法如下图所示。

3、广义表表示法
用广义表的形式表示根结点排在最前面, 用一对圆括号把它的子树结点括起来,子树结点用逗号隔开。树的广义表表示如下: 

(根结点(子结点(孙子结点,孙子结点),子结点(孙子结点,孙子结点)))

4、嵌套表示法
类似数学中所说的文氏图表示法,如下图所示。

二叉树的形态共有 5 种:空二叉树、只有根结点的二叉树、右子树为空的二叉树、左子树为空的二叉树和左、右子树非空的二叉树。二叉树的 5 种形态如图所示。

(1) 满二叉树(Full Binary Tree): 如果一棵二叉树只有度为 0 的结点和度为 2的结点, 并且度为 0 的结点在同一层上, 则这棵二叉树为满二叉树, 如图(a)所示。
由定义可知,对于深度为k的满二叉树的结点个数为 2k-1。

(2)完全二叉树(Complete Binary Tree):深度为 k,有 n 个结点的二叉树当且仅当其每一个结点都与深度为 k,有 n 个结点的满二叉树中编号从 1 到 n的结点一一对应时,称为完全二叉树,如下图(b)所示。 完全二叉树的特点是叶子结点只可能出现在层次最大的两层上, 并且某个结点的左分支下子孙的最大层次与右分支下子孙的最大层次相等或大 1。

性质 1 一棵非空二叉树的第i层上最多有 2
i-1个结点(i≥1)。
证明:采用数学归纳法进行证明。当n=1时,二叉树只有 1层,这一层只有根结点一个结点,所以第 1 层的结点数为 21-1=1,结论成立。假设当n=N时结论成立,即第N层最多有 2N-1个结点;当n=N+1 时,根据二叉树的定义,第N层的每个结点最多有 2个子结点,所以第N+1层上最多有 2N-1*2=2N=2(N+1)-1个结点,
结论成立。综上所述,性质 1成立。

性质 2 若规定空树的深度为 0,则深度为k的二叉树最多有 2
k-1 个结点(k≥0)。
证明:当k=0时,空树的结点数为 20-1=0,结论成立。当深度为k(k>0)时,
由性质 1可知,第i(1≤i≤k)层最多有 2i-1个结点,所以二叉树的最多结点数是:1+2^1+.......+2^(i-1)=2^i-1

性质 3 具有n个结点的完全二叉树的深度k-为log2n+1。
证明:根据性质 2和完全二叉树的定义可知,当一棵完全二叉树的结点数为n、深度为 k 时,有 2k-1-1<n≤2k-1
即 2k-1≤n<2k对不等式取对数,有 k-1≤log2n<k 由于k是整数,所以有k=log2n+1。 

性质 4 对于一棵非空二叉树,如果度为 0 的结点数目为n0,度为 2 的结点数目为n2,则有n0= n2+1。
证明:设n为二叉树的结点总数,n1二叉树中度为 1的结点数目,则有 n= n0+ n1+ n2在二叉树中,除根结点外,其余结点都有唯一的一个进入分支。设 B 为二叉树中的分支总数,则有 B=n-1 这些分支由度为1和度为2的结点发出的, 一个度为1的结点发出一个分支,一个度为 2的结点发出 2个分支,所以有 B= n1+2 n2  综合上面 3个式子,可以得到 n0= n2+1 

性质 5 对于具有 n 个结点的完全二叉树,如果按照从上到下和从左到右的顺序对所有结点从 1 开始编号,则对于序号为 i 的结点,有:
(1) 如果 i>1, 则序号为 i 的结点的双亲结点的序号为 i/2( “/” 表示整除);如果 i=1,则该结点是根结点,无双亲结点。
(2)如果 2i≤n,则该结点的左孩子结点的序号为 2i;若 2i>n,则该结点无左孩子。
(3)如果 2i+1≤n,则该结点的右孩子结点的序号为 2i+1;若 2i+1>n,则该结点无右孩子

这就是对二叉树的性质的基本介绍,下届从源代码的层次来进行实现。

时间: 2024-10-13 01:04:33

C#数据结构与算法揭秘七的相关文章

C#数据结构与算法揭秘六

这节我们讨论两种用的蛮多的数据结构--串和数组 首先,老样子,什么是串,这里串不是吃的牛肉串,羊肉串,而是字符串.在应用程序中使用最频繁的类型是字符串.字符串简称串,是一种特殊的线性表,其特殊性在于串中的数据元素是一个个的字符.字符串在计算机的许多方面应用很广.如在汇编和高级语言的编译程序中,源程序和目标程序都是字符串数据.在事务处理程序中,顾客的信息如姓名.地址等及货物的名称.产地和规格等,都被作为字符串来处理.另外,字符串还具有自身的一些特性.因此,把字符串作为一种数据结构来研究.具体情况,

C#数据结构与算法揭秘二

上文对数据结构与算法,有了一个简单的概述与介绍,这篇文章,我们介绍一中典型数据结构--线性结构. 什么是线性结构,线性结构是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这 种一对一的关系指的是数据元素之间的位置关系,即: (1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素: (2)除最后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是一个接一个的排

C#数据结构与算法揭秘二 线性结构_C#教程

上文对数据结构与算法,有了一个简单的概述与介绍,这篇文章,我们介绍一中典型数据结构--线性结构. 什么是线性结构,线性结构是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这 种一对一的关系指的是数据元素之间的位置关系,即: (1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素: (2)除最后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是一个接一个的排

C#数据结构与算法揭秘二_C#教程

上文对数据结构与算法,有了一个简单的概述与介绍,这篇文章,我们介绍一中典型数据结构--线性结构. 什么是线性结构,线性结构是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这 种一对一的关系指的是数据元素之间的位置关系,即: (1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素: (2)除最后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是一个接一个的排

C#数据结构与算法揭秘五

这节我们讨论了两种好玩的数据结构,栈和队列. 老样子,什么是栈, 所谓的栈是栈(Stack)是操作限定在表的尾端进行的线性表.表尾由于要进行插入.删除等操作,所以,它具有特殊的含义,把表尾称为栈顶(Top) ,另一端是固定的,叫栈底(Bottom) .当栈中没有数据元素时叫空栈(Empty Stack).这个类似于送饭的饭盒子,上层放的是红烧肉,中层放的水煮鱼,下层放的鸡腿.你要把这些菜取出来,这就引出来了栈的特点先进后出(First in last out).   具体叙述,加下图. 栈通常记

C#数据结构与算法揭秘19

这节,我们介绍基数排序和归并排序. 一.基数排序 基数排序(Radix Sort)的设计思想与前面介绍的各种排序方法完全不同.前面介绍的排序方法主要是通过关键码的比较和记录的移动这两种操作来实现排序的,而基数排序不需要进行关键码的比较和记录的移动.基数排序是一种借助于多关键码排序的思想,是将单关键码按基数分成多关键码进行排序的方法,是一种分配排序. 下面用一个具体的例子来说明多关键码排序的思想. 一副扑克牌有 52 张牌,可按花色和面值进行分类,其大小关系如下: 花色:梅花<方块<红心<

C#数据结构与算法揭秘九

这节,我们说一说二叉树常见的应用的场景.呵呵.............. 定义一个哈夫曼树,首先,要高清楚什么是哈夫曼树.所谓哈夫曼树是又叫最优二叉树,指的是对于一组具有确定权值的叶子结点的具有最小带权路径长度的二叉树. 介绍哈夫曼树的一些基本概念. (1)路径(Path):从树中的一个结点到另一个结点之间的分支构成这两个结点间的路径. (2)路径长度(Path Length):路径上的分支数. (3)树的路径长度(Path Length of Tree):从树的根结点到每个结点的路径长度之和.

C#数据结构与算法揭秘11

这节,我们说一说,图的基本源代码的源代码实现.具体情况,请听我一一给大家娓娓道来. 图的基本操作用一个接口来表示,为表示图的基本操作,同时给出了顶点类的实现.由于顶点只保存自身信息,所以顶点类 Node<T>很简单,里面只有一个字段 data. 顶点的类 Node<T>的实现如下所示. public Class Node<T> { private T data; //数据域 //构造器 public Node(T v) { data = v; } //数据域属性 pub

C#数据结构与算法揭秘八

这节重点讨论 树的结构的源代码实现. 先做一铺垫,讨论一下二叉树的存储结构.二叉树的存储结构分为线性存储和链式存储等等. 1.二叉树的顺序存储结构 对于一棵完全二叉树,由性质 5可计算得到任意结点 i 的双亲结点序号.左孩子结点序号和右孩子结点序号.所以,完全二叉树的结点可按从上到下和从左到右的顺序存储在一维数组中,其结点间的关系可由性质 5计算得到,这就是二叉树的顺序存储结构.下图所示的二叉树的顺序存储结构为: 但是,对于一棵非完全二叉树,不能简单地按照从上到下和从左到右的顺序存放在一维数组中