非线性结构讲解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例:先序遍历如图所示的二叉树
A
B
C
D
E
F
A B D G EC F H
G
H
例:中序遍历如图所示的二叉树
A
B
C
D
E
F
D G B E AF H C
G
H
例:后序遍历如图所示的二叉树
A
B
C
D
E
F
G D E B H FC A
G
H
练习:
A
先序遍历
B E
A B C D EF G H I J
C F G
中序遍历
DLR(先序遍历) LDR(中序遍历) LRD(后序遍历)
设二叉树的存储结构为二叉链表,其结点的类型定 义如下: typedef struct btreenod { elemtype data; struct btreenode *LC; struct btreenode *RC; } bnode; bnode *BT;
1、先序遍历:
先序遍历的递归定义为: 若二叉树为空,遍历结束,否则: (1)访问根结点; (2)按先序遍历方式遍历根结点的左子树; (3)按先序遍历方式遍历根结点的右子树;
二叉树的先序遍历算法
void preorder (bnode *BT) { if (BT= =NULL) return; else { visite (BT); /*访问BT指向的根结点*/ if (BT->LC != NULL) preorder (BT->LC); if (BT->RC != NULL) preorder (BT->RC); } }
B
B,C, D,E A B C D F,G C D, E A F,G C E
F,G
B
D
F
G
E
五、二叉排序树的生成
前面已给出了二叉排序树的定义,从二叉 排序村的定义可以得出二叉排序树的一个重要性 质:按中序遍历该树所得的中序序列是一个递增 有序列,因此,二叉排序树常用于对数据排序。 利用二叉排序树来组织数据,可以减少数据查找 次数,提高效率。 由给定的数据序列生成二叉排序树的过程是 在二叉排序树上插入结点的过程:对一序列{k1, k2,…,kn},先设一棵空二叉排序树,然后将序 列中的元素顺次生成结点后逐个插入。插入步骤 如下:
有一棵子树的情况下也要明确该子树是左子树还是右 子树,而树中不区分子树顺序。
几个关于二叉树的概念 (1)满二叉树:
在一棵二叉树中,如果 所有非叶子结点都存在 左右子树,并且所有叶 结点都在同一层上,这 样的一棵二叉树称作满 二叉树。
D 4 H 8 I 9 J 10 B 2 E 5 K 11
A
1
C 3 F 6 L 12 M 13 N 14 G 7 O 15
后序遍历的递归定义为:
若二叉树为空,遍历结束,否则: (1)按后序遍历方式遍历根结点的左子树; (2)按后序遍历方式遍历根结点的右子树; (3)访问根结点;
二叉树的后序遍历算法
void postorder (bnode *BT) { if (BT= =NULL) return; else { if (BT->LC != NULL) postorder (BT->LC); if (BT->RC != NULL) postorder (BT->RC); visite (BT); /*访问BT指向的根结点*/ } }
第一步:k1作为二叉排序树的根。 第二步:若k2<k1,则k2所在结点应插人到k1的 左子树 上;否则,插入到k1的右子树上。 第三步:读入ki, ki < k1 (根),则进入左子树,否则 进入右子树,继续与子树之根比 较,直到某结点kj,若 有ki < kj且结点kj的左子树为空,则结点ki 插入到结点kj 的左子树; 若有ki>kj且结点kj的右子树为空,则结点ki插入到 结点kj的右子树。
(2)如果2i≤n,则序号为i的结点的左子结点的序号为2i ; (3)如果2i+1≤n,则序号为i的结点的右子结点的序号为2i +1; 满二叉树和完全二叉树中结点的序号可以唯一地反应出结点之 间的逻辑关系。 A B C D E F G H I J K L
结点序号 1
2
3
4
5
6
A
7
8
9
10 11 12
Root
B
A
第一层
D
C
第二层
I
E
F
G
H
第三层 第四层
J
(1)叶子
没有后继的结点称为叶子(或终端端结点),图1.23 中的结点D、E、F、G、H、J为终端结点; (2)分支结点 非叶子结点称为分支结点 (或:非终端结点)。 (3)结点的度 一个结点的子树数目称为该结点的度。B的度为2, 结点C的度为3;D、J的度为0; (4)树的度 树中各结点的度的最大值称为该树的度,上图所示 的树的度为3。
根据以上二叉树的递归定义,可以知道,二叉树可 以为空集,或者只有根结点左右子树为空,或者只有左 子树或右子树,或者左右子树都存在。二叉树的五种形 态如下图所示。
空二叉树
仅有一个结 点的二叉树
根的左子树非空根的 右子树为空的二叉树
根的左子树为空根的 右子树非空的二叉树
根的左右子树皆 为非空的二叉树
一般树与二叉树在概念上的区别 *树至少有应有一个结点,而二叉树可以是空; *二叉树的结点的子树要区分左子树和右子树,即使只
(5)子结点 某结点子树的根称为该结点的子结点。 (6)父结点 相对于某结点子树的根,称该结点为子树 根的父结点。 (7)兄弟 具有同一父结点的子结点称兄弟。 如图结点C是结点G、H、I的父结点;结点G、H、I是结 点C的子结点。J结点是结点I的子结点;结点G、H、I互为兄 弟。 (8)结点的层次 根结点的层次为1,其他任何的层等于它的 父结点的层数加1。 (9)树的深度 一棵树中,结点的最大层次值就是树的深度。 图所示的树的深度为4。 (10)有序树和无序树 如果一棵树中结点的各子树从左到右 是有序的,即若交换了某结点各子树的相对位置则构成了不同 的树,称这棵树为有序树,反之则为无序树。 (11)森林 森林是n棵树的集合(n>0)。任何一棵树,删去 根结点,树就变成了森林。
§1.3 非线性结构
非线性结构的逻辑特征是一个结点元素可能 有多个直接前趋和多个直接后继。最主要的非线 性结构是树结构和图结构。 1.3.1树结构及其基本概念 树结构是一类重要的非线性结构。树结构是 结点之间有分支、层次关系的结构,在客观世界 中,树结构是大量存在的,例如家谱、行政组织 机构都可用树形象地表示。在计算机领域中,树 结构也被广泛应用,如计算机磁盘文件的管理, 是一种从根目录到各级子目录的分层结构i在数据 库系统中,常采用树来组织数据信息。
1.3.2二叉树结构
二叉树是一类非常重要的非线性结构,许多 实际问题抽象出来的数据结构往往都是二叉树, 即使一般的树结构也能简单地转换为二叉树。
一、二叉树的基本概念
二叉树的递归定义
二叉树是n个接点的有限集合(n≥0);这个集合可 以是空(即n=0),此时称为为空二叉树;或者由一个根 结点和两棵互不相交的被称为根的左子树和右子树组成, 左子树和右子树分别又是一棵二叉树。
例6 已知一棵二叉树的先序遍历序列为ABCDEFGHIJ.中 序遍历序列为CBDEAFHIGJ,试构造这棵二叉树。构造过 程由图示如下: A A
B
C,B, D,E A B C D F G C F,H,I G,L C D, E A
F
H,I G,L
B
D
F
GFra Baidu bibliotek
E
H, I
J
E
H
I
J
练习:已知一棵二叉树的先序遍历序列为ABCDEFG.中序 遍历序列为CBEDAFG,试构造这棵二叉树。 A A
二叉树链表的结点结构
LC Data RC
右指针域,指向结点的右子树根 数据域 左指针域,指向结点的左子树根
对于二叉树链表,如果某结点的左子树或右子树为 空,则相应的指针域为“空”。此外还设置一指针变量指 向 二叉树的根结点,称为头指针。二叉链表的头指针可以 唯一地确定一棵二叉树。 对于二叉树链表,可以比较方便的从某个结点出发 查找子女结点,但是要从某个结点出发查找其父结点就 比较麻烦。因此可以采用三叉链表。
B
C
D
E
F
G
H
I
J
K
L
然而对于一般的二叉树,如果按照从上到下,从左 到右的顺序将树中的结点顺序存储在一维数组中,则数 组元素下标之间的关系不能够反映二叉树中结点之间的 逻辑关系。这时可以将一般二叉树进行改造,人为添加 一些并不存在的空结点,使之成为一棵完全二叉树的形 式,然后再用一维数组存储。但是,这样可能会造成大 量的存储空间的浪费,尤其是那些右单支二叉树。对于 这样的情况,比较适合的方式是采用链式存储方式存储。
8
4
10 4
1
9 6
17
1
12
二叉排序树
二、二叉树的存储结构
二叉树的存储方式分为顺序存储和链式存储两种。
顺序存储方式 是把二叉树的所有结点按照一定的次序存
储到一片连续的存储单元中,实际上就是把二叉树这种 非线性结构线性化。
对于满二叉树和完全二叉树具有性质: 对于有 n 个
结点的满二叉树和完全二叉树,如果从上至下和从左 至右的顺序对二叉树中的所有结点从 1 开始顺序编号, 则对于任意序号i的结点有: ( 1 ) 如 果 i>1 , 则序 号为 i 的结 点的父 结 点的序 号 为 i/2 (取整);如果i=1,则结点是根结点,无父结点;
(2)完全二叉树: 在一棵二叉树中,如果至多只有
最下面两层上的结点的度数可以小于2,并且最下一层 的结点都集中在该层最左边的若干位置上,则此二 叉树称为完全二叉树。
A A
B
C
B
C E
D
E
F
G H
D
F K
G L
H
I
J
K
L
I
J
完全二叉树
非完全二叉树
(3)二叉排序树:它或者是空二叉树,或者是具有如
下性质的二叉树:左子树上所有结点的关键字均小于 根结点的关键字;右子树上所有结点的关键字均大于 等于根结点的关键字。左子树和右子树本身又各是一 棵二叉排序树。
B C DA F E H J I G
D
H
I
后序遍历 DC B F J I H G E A
J
四、根据遍历序列构造二叉树 由一棵给定的二叉树可以获得三种遍历序列,同样, 也可以由这些遍历序列来重新构造二叉树。单用一个遍 历序列是无法构造二叉树的,因为无法从遍历序列中区 分二叉树的左、右子树,但利用中序遍历序列,并结合 先序遍历序列和后序遍历序列中任何一个序列就能重新 构造二叉树。 第一步:从先序遍历序列中取出第一个结点,该结点一 定是二叉树的根。然后在中序遍历序列中找出根结点, 根结点前面的结点序列就是左子树的中序遍历序列,根 结点后面的结点序列就是右子树的中序遍历序列。 第二步:对根的左子树先序遍历序列和中序追历序列及 右子树的先序遍历序列和中序遍历序列。再执行第一步, 直到得出所有叶子结点为止。
遍历 是树结构的基本操作。树遍历的含义是指用一
定的规律走遍树的每一个结点,使每个结点被访问一次 而且只被访问一次。 任何一棵二叉树都由三部分组成:即根结点(记作 D )、左子树(记作 L )、右子树(记作 R )。这样遍历 一棵二叉树的次序有六种: DLR 、 LDR 、 LRD 、 DRL 、 RDL 、 RLD 。如果限定左右子树的访问是先左后右,则 只有三种:
LC Data Parent RC
右指针域,指向结点的右子树根
父节点指针域 数据域
左指针域,指向结点的左子树根
A B
A ^
A ^ ^
B
^ C ^
B
C
D
D
^ C
^
D
E
F
^ E ^
^ F ^
^ E
^
^ F
^
(a) 二叉树
(b) 二叉链 表结构
(c) 三叉链表结构
一棵二叉树的链式存储结构
三、二叉树的遍历
中序遍历的递归定义为:
若二叉树为空,遍历结束,否则: (1)按中序遍历方式遍历根结点的左子树; (2)访问根结点; (3)按中序遍历方式遍历根结点的右子树;
二叉树的中序遍历算法
void inorder (bnode *BT) { if (BT= =NULL) return; else { if (BT->LC != NULL) inorder (BT->LC); visite (BT); /*访问BT指向的根结点*/ if (BT->RC != NULL) inorder (BT->RC); } }
树结构非常类似于自然界中的树,也有树根、树 叶及联系它们的支干。不过这里指的树结构是一种 倒生树,可以用递归的方式定义如下: 树是一个或多个结点元素组成的有限集合T,且 满足如下条件: (1)有一个特定的结点元素,称为根结点Root; (2)其余结点元素分成m个(m>0)互不相交 的有限集T1,T2,…,Tm,其中每个集又都是一棵 树,这些树称为Root的子树。 在树中,一个结点元素常简称结点,采用递归 方式定义树结构,揭示出树的固有特性。实际上, 树中的每个结点都是该树中某一子树的根。
相关文档
最新文档