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