一,引言
二叉树作为一种基础数据结构,这里仅仅对概念性知识进行简略概括,主要进行讲解二叉树的前中后序遍历,节点个数,叶子节点个数,二叉树高度。
二,概念及性质
结点的度:一个结点含有的子树的个数称为该结点的度; 如上图:A的为 6
叶结点或终端结点:度为0的结点称为叶结点; 如上图:B、C、H、I...等结点为叶结点
双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点.
孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点
树的度:一棵树中,最大的结点的度称为树的度; 如上图:树的度为6。
这里主要几个常用的进行点一下。
还有一些相对重要的性质:
1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点
2. 若规定根结点的层数为1,则深度为h的二叉树的最大结点数是2^h-1;
3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0,, 度为2的分支结点个数为n2,n0 = n2 +1;
三,前中后序遍历
1,前序遍历:
前序遍历:根-->左子树-->右子树,注意是每一个子树都进行这个顺序。
首先是(1)作为整个二叉树的根,先进行遍历之后是(2),(2)作为左子树的根,遍历左子树(4),(4)作为2左子树的根,左子树为空,右子树(6)。此时2的左子树结束,走右子树(5)。
此时1的左子树走完,走右子树(3)。
总结:1-->2-->4-->6-->5-->3 。
展开图:
代码实现:
void BinaryTreePrevOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
printf("%d", root->_data);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
2,中序遍历
中序遍历:左子树-->根-->右子树,每个子树都按这个方式遍历。
首先1作为根,走左子树,2作为新的根继续找左子树4,4作为根左子树为空继续走根节点(4),右子树(6),2作为根节点左子树走完,走根(2)进而右子树(5),1的左子树走完继续走根(1),右子树(3)。
总结:4-->6-->2-->5-->1-->3.
展开图:
每一个框架一个递归循环。
代码实现:
void BinaryTreeInOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreePrevOrder(root->_left);
printf("%d", root->_data);
BinaryTreePrevOrder(root->_right);
}
3,后序遍历:
后序遍历:左子树-->右子树-->根,每一个子树 都按照这个顺序进行递归。
首先1作为根,左子树2,2作为根进行走左子树4,4同样作为根走左子树,左子树为空,走右子树(6),进而走根(4),此时2的左子树完毕,走右子树(5),进而走根(2),1的左子树完毕,走右子树(3),最后走根(1)。
总结:6-->4-->5-->2-->3-->1。
代码实现:
void BinaryTreePostOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
printf("%d", root->_data);
}
四,节点个数
求该二叉树节点的个数也就是说有多少个节点。
代码思路:
每次经过一个节点数量加一,总节点个数 = 左节点个数 + 右节点个数。
代码实现:
int BinaryTreeSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right) + 1;
}
五,叶子节点个数
代码思路:
当该节点的左孩子和右孩子同时为空时,则该节点为叶子节点。将整个二叉树遍历一遍满足加一,不满足就继续走递归。
int BinaryTreeLeafSize(BTNode* root)
{
if (root == NULL)
{
return 0;
}
if (root->_left == NULL && root->_right == NULL)
{
return 1;
}
return BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
}
六,二叉树高度
分支最长的为二叉树高度,总的来说就是返回左子树和右子树的较大值。
代码实现:
int BinaryTreeTall(BTNode* root)
{
if (root == NULL)
{
return 0;
}
int a = BinaryTreeTall(root->_left);
int b = BinaryTreeTall(root->_right);
return a > b ? BinaryTreeTall(root->_left) + 1 : BinaryTreeTall(root->_right) + 1;
}
这个相对来说比较复杂,通过变量记录左孩子和右孩子的大小,之后比较这个的大小,大的数据进行加1操作。进而进行比较,依次往复。以这个为例子画一些递归展开图。
如图以下面二叉树为例:
没有地方了,右子树和左子树的方法相同,在递归的学习中不理解就可以画递归展开图。
七,总结:
在递归的学习中只要不懂就画递归展开图,很有助于对递归的理解。