树是n
个结点的有限集。
1)n > 0
时根结点是唯一的,不可能存在多个根结点。
2)m > 0
时,子树的个数没有限制,但它们一定是互不相交的。
树中结点的最大层次称为树的深度或高度。
如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树为有序树,否则称为无序树。
在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。
其中data
是数据域,存储结点的数据信息。
而parent
的指针域,存储该结点的双亲在数组中的下标。
把每个结点的孩子结点排列起来,以单链表作存储结构,则n
个结点有n
个孩子链表,如果是叶子结点则此单链表为空。然后n
个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中。
设计了两种结点结构,一个是孩子链表的孩子结点。
其中child
是数据域,用来存储某个结点在表头数组中的下标。next
是指针域,用来存储指向某结点的下一个孩子结点的指针。
另一个是表头数组的表头结点,如下图所示:
其中data
是数据域,存储某结点的数据信息。firstchild
是头指针域,存储该结点的孩子链表的头指针。
结点结构如下表:
其中data
是数据域,firstchild
为指针域,存储该结点的第一个孩子结点的存储地址,rightsib
是指针域,存储该结点的右兄弟结点的存储地址。
二叉树是n
个结点的有限集合,该集合或者为空集,或者由一个根节点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。
2)二叉树的左右子树是有顺序的,次序不能任意颠倒
3)即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。
1)在二叉树的第i
层上至多有 2 i − 1 2^{i-1} 2i−1个结点。
2)深度为k
的二叉树至多有 2 k − 1 2^{k}-1 2k−1个结点
3)对任何一棵二叉树T
,如果其终端结点数(叶子结点数)为 n 0 n_0 n0,度为2的结点数为 n 2 n_2 n2,则 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1
4)具有n
个结点的完全二叉树的深度为 [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1([x]表示不大于x的最大整数)
5)如果对一棵有n
个结点的完全二叉树的结点按层编号(从第1层到第 [ l o g 2 n ] + 1 [log_2n]+1 [log2n]+1层,每层从左到右),对任一结点i
有:
a.如果i=1
,则结点i
是二叉树的根,无双亲;如果i>1
,则其双亲是结点[i/2]
b.如果2i>n
,则结点i
无左孩子;否则其左孩子是结点2i
c.如果2i+1>n
,则结点i
无右孩子;否则其右孩子是结点2i+1
二叉树每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,这样的链表叫做二叉链表。
其中data
是数据域,lchild
和rchild
都是指针域,分别存放指向左孩子和右孩子的指针。
二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
1)前序遍历
若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。
2)中序遍历
若树为空,则空操作返回,否则从根结点开始,中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。
3)后序遍历
若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。
4)层序遍历
若树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在同一层中,从左到右的顺序对结点逐个访问。
不同的遍历提供了对结点依次处理的不同方式,可以在遍历过程中对结点进行各种处理。