写在前面
在计算机领域中,树作一种重要的数据结构存在。从解决集合归属问题,到动态查询名次问题,都有树的影子。本次博客的主要目标是:带领大家了解树的基本结构。
今日概念
实际上,你可以把调用函数认为是将函数压到一个栈里面,不断执行栈顶的函数。执行完后,就将其弹出。可以用这种形式去理解递归。
问题引入
当大家想到树,第一反应便是物理意义上的树吧。但事实上,计算机里的树结构长这样:
以这个树为例,来剖析树的各个基本概念。
-
定义:树形结构是指数据元素之间存在“一对多”的关系,从上而下查看,1指向2,3;2又指向4,5,能够在其中发现一定的递归的影子。
-
结点(node):树中用于存储数据的位置,图中共有7个结点。
-
根结点(root):整个树呈"倒Y"结构,其中,最顶上的点为根结点(和现实树正好相反)——编号为1的结点。
-
父结点(father)和子结点(child):相对的概念,对于一个结点来说,它一定有一个父结点(除了根节点),可以有多个子结点。根据这条性质,我们能够证明:对于一个 N N N个结点组成的树,它有且仅有 N − 1 N-1 N−1条边。并且,树上的任意两个结点有且只有一条可走的路径。
-
内结点(external)和叶子结点(leaf):叶子结点为没有子结点的点。如图,4,5,6,7为此树的4个叶子结点。除了根结点和叶子结点,其他的结点为内结点。
-
深度(depth):深度从上往下依次递减,顶点为0,如结点5的深度为2。可以发现,一个结点的深度等于它到根结点的距离。
-
子树:每个结点可能有左子树和右子树,每个子树都是一颗树。在不断递归的过程中,会保持树的结构完整。
算法分析
在树形结构中,会出现非常多的问题需要解决。这里列出了一些需要思考的问题:
-
证明:对于一个 N N N个结点组成的树,它有且仅有 N − 1 N-1 N−1条边。并且,树上的任意两个结点有且只有一条可走的路径。
-
二叉树(Binary Tree)和多叉树(k-ary Tree):二叉树中每个结点至多有两个子结点;k叉树中每个结点至多有k个子结点。
-
树的遍历(Traversing a Tree):
树的遍历有四种方法,分别为根左右(Pre-order Traversal)、左右根(Post-order Traversal、左根右(In-order Traversal)、层序遍历(Level Traversal)、前三种可用深度优先搜索(DFS, Depth First Search),后者可用广度优先搜索(BFS, Breadth First Search)。
-
由于树的性质,使得如果从根结点开始对树进行操作,在递归寻找到他的子结点的时候,树的形式是不被破坏的,在下一篇博客中我会主要讲解如何利用该性质来解决一些有关树的问题。
其他博客(暂无)
- 用C++写出一颗完备的多叉树
- 树形结构(二):树上DFS操作集锦
- 堆的应用:同样是树形结构,堆怎么就这么厉害?
- 树的直径是啥玩意?
上DFS操作集锦