一、树的定义

一棵树是由n(n>0)个元素组成的有限集合,其中:

(1)每个元素称为结点(node)

(2)有一个特定的结点,称为根结点或树根(root)

(3)除根节点外,其余节点能分成m(m>=0)个互不相交的有限集合 T(0)-T(m-1)。其中的每一个子集都是一个树,这些集合被称为这棵树的子树。

如下图是一棵树: image

二、树的基本概念

  • 树是由递归定义的
  • 一棵树中至少有1个结点。这个节点就是根节点,他没有前驱,其余每个节点都有且只有一个前驱节点。每个节点可以有任意个后继结点。因此,树是非线性结构,但也是有序结构。
  • 一个节点的子树个数称为这个结点的度,例如上图根节点的度为2。度为0的结点被称为叶结点;度不为0的结点被称为分支结点,根以外的分支节点称为内部结点,树中各节点的度的最大值称为这棵树的度。
  • 在用图形表示的树形结构中,对两个用线段(我们称为树枝)连接的相关联的结点,称上端结点为下端节点的父节点,反之为子节点。
  • 定义一棵树的根的层次为1,其他结点的层次等于他的父节点的层次加一。一棵树中所有节点的层次的最大值称为这棵树的深度。
  • 对于树中任意两个不同的结点,从一个结点出发一定能到达另一个结点。
  • mm (m>=0)棵树的结合称为森林。

三、树的基本术语

  • 节点的度:一个节点含有的子树的个数称为该节点的度;
  • 叶节点或终端节点:度为0的节点称为叶节点;
  • 非终端节点或分支节点:度不为0的节点;
  • 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
  • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点;
  • 树的度:一棵树中,最大的节点的度称为树的度;
  • 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
  • 树的高度或深度:树中节点的最大层次;
  • 堂兄弟节点:双亲在同一层的节点互为堂兄弟;
  • 节点的祖先:从根到该节点所经分支上的所有节点;
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
  • 森林:由m(m>=0)棵互不相交的树的集合称为森林;

四、二叉树基本概念

二叉树(binary tree,简称BT),是一种特殊的树,它的度是2。一个节点有两个子节点,其中左边的是左子节点,右边的是右子节点。左边的叫左子树,右边的叫右子树。

五、二叉树的性质

  • 在二叉树的第 i 层上最多有 2i12^{i-1} 个结点(i>=1)
  • 深度为 kk 的二叉树至多有 2k12^{k}-1 个结点(k>=1)
  • 特别的,深度为 kk ,且有 2k12^{k}-1 个结点的二叉树称为满二叉树。
  • 对于任意一棵二叉树,如果其叶子结点数为 n0n_0 ,度为 2 的结点数为 n2n_2 ,那么 n0=n2+1{n_0}={n_2}+1
  • 具有 n 个结点的完全二叉树的深度为 floor(log2 n)+1floor(log_2\space n)+1

六、(二叉)树的遍历

在解决问题时,常常要按照某种次序来获取树中全部节点的信息,这种操作叫做树的遍历。

二叉树的遍历方式主要可以分为四种:前序遍历、中序遍历、后序遍历和层序遍历。

  • 先序遍历 先访问根节点,然后按照左右先后顺序遍历各子树(根左右)
  • 中序遍历 先访问左子树,然后访问根,最后访问右子树(左根右)
  • 层次遍历 按层次的大笑从小到大遍历,同一层次按照从左到右的顺序。
  • 后序遍历 先按照左右先后顺序遍历各子树,然后访问根(左右根)

前序遍历、中序遍历和后序遍历就是中的位置不一样,前序遍历就是中左右,中序遍历就是左中右,后序遍历就是左右中。

前中后序遍历都是深度搜索,层序遍历是广度搜索。

七、⼆叉树的种类

⼆叉树有两种主要的形式:满⼆叉树完全⼆叉树

八、满二叉树

在一棵二叉树中,如果所有的分支节点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树成为满二叉树。

image

九、完全二叉树

对一棵具有n个结点的二叉树按层序编号,如果编号为 i(1 ≤ i ≤ n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中的位置完全相同,则这棵二叉树称为完全二叉树

image

十、⼆叉树遍历的实现(代码)

  • 先序遍历
void preorder (int root)
{
	if (root != -1)       //跳出递归条件 
	{
		cout << data[root] << " ";
		preorder(lchild[root]);
		preorder(rchild[root]);
	}
}
  • 中序遍历
void midorder (int root)
{
	if (root != -1)       //跳出递归条件 
	{
		preorder(lchild[root]);
		cout << data[root] << " ";
		preorder(rchild[root]);
	}
}
  • 后序遍历
void postorder (int root)
{
	if (root != -1)       //跳出递归条件 
	{
		preorder(lchild[root]);
		preorder(rchild[root]);
		cout << data[root] << " ";
	}
}

参考文章:【数据结构/C++】 树详解

📝我的个人主页

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​

💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊

✉️今天你做别人不想做的事,明天你就能做别人做不到的事♐