数据结构树之切腹攻略

树 —— 一种一对多的数据结构。

目录

1. 树的相关术语

2. 树形结构的各种表示法

2.1 树形表示法

2.2 形式语言表示法

2.3 文氏图表示法

2.4 嵌套括号表示法

2.5 凹入表表示法

2.6 图书目录,杜威表示法

3. 森林

3.1 树转化成二叉树

3.2 二叉树转化成树

3.3 森林转化成二叉树

3.4 二叉树转化成森林

4. 森林的遍历

4.1 先根深度优先遍历森林 = 前序法遍历二叉树(根左右)

4.2 后根深度优先遍历森林 = 按中序法遍历对应的二叉树(左根右)

4.3 宽度(广度)优先遍历森林

5 树的链式存储结构

5.1 “子结点表”表示方法

​5.2 静态“左孩子/右兄弟”表示法

​5.3 动态表示法

​5.4 动态“左孩子/右兄弟”表示法

​5.5 父指针表示法(应用于并查集)

6 并查集

6.1 等价关系

(1)定义

(2)例子

6.2 等价类(equivalence classes)

(1)定义

(2)用树来表示等价类的并查

6.3  路径压缩

7 树的顺序存储结构

7.1 带右链的先根次序表示(Stack)

​7.2 带双标记的先根次序表示(Stack)

7.3 带双标记的层次次序表示(Queue)

7.4 带度数的后根次序表示(Stack)

8 K叉树


1. 树的相关术语

下面引入术语的专业解析(觉得烦死人的,可以略过)

RootThe top node in a tree.树的顶端结点
ChildA node directly connected to another node when moving away from the Root.孩子当远离根(Root)的时候,直接连接到另外一个结点的结点被称之为孩子(Child);
ParentThe converse notion of a child.双亲相应地,另外一个结点称为孩子(child)的双亲(parent)。
SiblingsA group of nodes with the same parent.兄弟具有同一个双亲(Parent)的孩子(Child)之间互称为兄弟(Sibling)。
AncestorA node reachable by repeated proceeding from child to parent.祖先结点的祖先(Ancestor)是从根(Root)到该结点所经分支(Branch)上的所有结点。
DescendantA node reachable by repeated proceeding from parent to child.子孙反之,以某结点为根的子树中的任一结点都称为该结点的子孙(Ancestor)。
LeafA node with no children.叶子(终端结点)没有孩子的结点(也就是度为0的结点)称为叶子(Leaf)或终端结点。
BranchA node with at least one child.分支(非终端结点)至少有一个孩子的结点称为分支(Branch)或非终端结点。
DegreeThe number of sub trees of a node.结点所拥有的子树个数称为结点的度(Degree)。
EdgeThe connection between one node and another.一个结点和另一个结点之间的连接被称之为边(Edge)。
PathA sequence of nodes and edges connecting a node with a descendant.路径连接结点和其后代的结点之间的(结点,边)的序列。
LevelThe level of a node is defined by 0 + (the number of connections between the node and the root).层次结点的层次(Level)从根(Root)开始定义起,根为第0层,根的孩子为第1层。以此类推,若某结点在第i层,那么其子树的根就在第i+1层。
Height of nodeThe height of a node is the number of edges on the longest path between that node and a leaf.结点的高度结点的高度是该结点和某个叶子之间存在的最长路径上的边的个数。
Depth of nodeThe depth of a node is the number of edges from the tree’s root node to the node.结点的深度结点的深度是从树的根结点到该结点的边的个数。 (注:树的深度指的是树中结点的最大层次。)
ForestA forest is a set of n ≥ 0 disjoint trees.森林森林是n(>=0)棵互不相交的树的集合。

2. 树形结构的各种表示法

2.1 树形表示法

2.2 形式语言表示法

2.3 文氏图表示法

2.4 嵌套括号表示法

2.5 凹入表表示法

2.6 图书目录,杜威表示法

3. 森林

森林(forest)零棵多棵不相交的树的集合(通常是有序)
树与森林的对应
(1)一棵树,删除树根,其子树就组成了森林
(2)加入一个结点作为根,森林就转化成了一棵树

3.1 树转化成二叉树

3.2 二叉树转化成树

3.3 森林转化成二叉树

3.4 二叉树转化成森林

4. 森林的遍历

4.1 先根深度优先遍历森林 = 前序法遍历二叉树(根左右)

先根序列 A B C K D E H F J G

4.2 后根深度优先遍历森林 = 按中序法遍历对应的二叉树(左根右)

后根序列 B K C A H E J F G D

4.3 宽度(广度)优先遍历森林

森林广度优先:A D B C E F G K H J

二叉树根据二叉链存储结构的右斜线(优先访问右子树)

5 树的链式存储结构

5.1 “子结点表”表示方法

list of children,就是图的邻接表


5.2 静态“左孩子/右兄弟”表示法


5.3 动态表示法

每个结点分配可变的存储空间

- 子节点数目发生变化,需要重新分配存储空间


5.4 动态“左孩子/右兄弟”表示法


5.5 父指针表示法(应用于并查集)

父指针(parent pointer)表示法:只需要保存一个指向其父结点的指针域

涉及算法:

6 并查集

并查集:一种特殊的集合,由一些不相交子集构成。

——Find:查询结点所在集合

——Union:归并两个集合

6.1 等价关系

(1)定义

设 R 是集合 A 上的一个二元关系,若R满足:

自反性:∀ a ∈A, => (a, a) ∈ R

对称性:(a, b) ∈R∧ a ≠ b => (b, a)∈R

传递性:(a, b)∈R,(b, c)∈R =>(a, c)∈R

则称R是定义在A上的一个等价关系。设R是一个等价关系,若(a, b) ∈ R,则称a等价于b,记作 a ~ b

(2)例子

同班同学关系、同乡关系是等价关系。

平面几何中三角形间的相似关系、全等关系都是等价关系。

平面几何中直线间的平行关系是等价关系。

6.2 等价类(equivalence classes)

(1)定义

等价类:相互等价的元素所组成的最大集合。

江湖上散落着各式各样的大侠,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的帮派,通过两两之间的朋友关系串联起来。而不在同一个帮派的人,无论如何都无法通过朋友关系连起来,于是就可以放心往死了打。但是两个原本互不相识的人,如何判断是否属于一个朋友圈呢?

我们可以在每个朋友圈内推举出一个比较有名望的人,作为该圈子的代表人物。这样,每个圈子就可以这样命名“华山派”,“峨眉派”等,两人只要互相比对一下自己的队长是不是同一个人,就可以确定敌友关系了。

但是还有问题啊,大侠们只知道自己直接的朋友是谁,很多人压根就不认识队长,要判断自己的队长是谁,只能漫无目的的通过朋友的朋友关系问下去:“你是不是队长?你是不是队长?”想打一架得先问个几十年,饿都饿死了。这样不仅效率低,还有可能陷入无限循环中。于是队长下令,重新组队。队内所有人实行分等级制度,形成树状结构,我队长就是根节点,下面分别是二级队员、三级队员。每个人只要记住自己的上级是谁就行了。遇到判断敌友的时候,只要一层层向上问,直到最高层,就可以在短时间内确定队长是谁了。由于我们关心的只是两个人之间是否是一个帮派的,至于他们是如何通过朋友关系相关联的,以及每个圈子内部的结构是怎样的,甚至队长是谁,都不重要了。所以我们可以放任队长随意重新组队,只要不搞错敌友关系就好了。于是,门派产生了。

(参考自:超有爱的并查集~超有爱的并查集~

(2)用树来表示等价类的并查

UNION/FIND算法示例(门派合并)

(1)

(2)

(3)

F的父节点为D,再依据加权合并规则,以F为根的树结点个数少,故将F指向D。

6.3  路径压缩

查找时最理想的情况就是所有人的直接上级都是掌门,一共就两级结构,只要找一次就找到掌门了。哪怕不能完全做到,也最好尽量接近。这样就产生了路径压缩算法

 两个互不相识的大侠碰面了,想知道能不能干一场。 于是赶紧打电话问自己的上级:“你是不是掌门?” 上级说:“我不是呀,我的上级是谁谁谁,你问问他看看。” 一路问下去,原来两人的最终boss都是东厂曹公公。 “哎呀呀,原来是自己人,有礼有礼,在下三营六组白面葫芦娃!” “幸会幸会,在下九营十八组仙子狗尾巴花!” 两人高高兴兴地手拉手喝酒去了。 “等等等等,两位大侠请留步,还有事情没完成呢!”我叫住他俩。 “哦,对了,还要做路径压缩。”两人醒悟。 白面葫芦娃打电话给他的上级六组长:“组长啊,我查过了,其实偶们的掌门是曹公公。不如偶们一起结拜在曹公公手下吧,省得级别太低,以后查找掌门麻烦。” “唔,有道理。” 白面葫芦娃接着打电话给刚才拜访过的三营长……仙子狗尾巴花也做了同样的事情。 这样,查询中所有涉及到的人物都聚集在曹公公的直接领导下。每次查询都做了优化处理,所以整个门派树的层数都会维持在比较低的水平上。

7 树的顺序存储结构

7.1 带右链的先根次序表示(Stack)

结点按先根次序顺序存储在一片连续的存储单元中


7.2 带双标记的先根次序表示(Stack)

结点按先根次序顺序存储在一片连续的存储单元中

有0无1

7.3 带双标记的层次次序表示(Queue)

结点按层次次序顺序存储在一片连续的存储单元中

7.4 带度数的后根次序表示(Stack)

结点按后根次序顺序存储在一片连续的存储单元中

8 K叉树

K叉树:每个父节点最多有K个子节点。

二叉树的许多性质可以推广到 K 叉树


话说,这篇文章跟切腹有啥关系?当然是木有。


本文主要参考自

张铭《数据结构与算法》

程杰《大话数据结构》

《超有爱并查集~》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值