📖 点击展开/收起 文章目录
文章目录
树的概念
在讲解二叉树之前,我们先提一嘴树的概念,不同于我们之前学到的栈与队列,链表顺序表,树是一种非线性结构 ,下面我具体讲讲树的概念.
首先树的子树与子树之间不可相连,子树与其他树的孩子也不可相连

树的基础概念
如下图就是一颗树:

1.节点的度是指,如上图A节点他连了三个子树,它的度就为3,节点的度就是该节点子树个数
2.树的度 : 树的度就是一棵树中,度最大的节点的度 eg:在上图中树的度为三
3.叶节点: (又称为终端节点),也就是度为零的节点
4.父节点: ,含有子节点的节点成为它的父节点的子节点,eg:子节点B C D的父节点就是A
5.兄弟节点: ,就是在同一行,具有相同父节点的节点
6.结点的层次: ,从根节点定义为第一层,往下层数相加
7.树的高度,: 总层数就是树的高度
8.堂兄弟节点: 双亲在同一层的互为堂兄弟节点
9.根节点: 就是最顶上的节点 也就是A
c
typedef int DataType;
struct Node
{
struct Node* firstChild1; // 第一个孩子结点
struct Node* pNextBrother; // 指向其下一个兄弟结点
DataType data; // 结点中的数据域
}
森林
在树的基础概念之上 ,我们引出了森林;
如图所示:

在森林中没有共同的根节点,是一群树的集合
树和森林的存储
通常,我们是把树和森林,以二叉树地形式来存储
typedef int DataType;
c
struct Node
{
struct Node* firstChild1; // 第一个孩子结点
struct Node* pNextBrother; // 指向其下一个兄弟结点
DataType data; // 结点中的数据域
}


如果是森林的话,去掉Aj节点就好了
二叉树存储森林和树区别:树变二叉树没有右孩子,森林变二叉树有右孩子
下面我们来观察一下
树的后续遍历与他变成的二叉树的中序遍历
树的后序遍历:DHIEFBGCA
树变的二叉树的中序遍历:DHIEBGCA
我们会发现树的后序遍历与他对映的二叉树中序遍历一致
森林的遍历方式是把这里为例子,森林后序遍历,就是从左到右,每颗小树的后续遍历按照从左到右顺序拼起来
同理也得: 我们会发现森林的后序遍历与他对映的二叉树中序遍历一致
二叉树
根据树的定义二叉树就是一种特殊的树,它的度不大于2,意思是他一个节点最多有两个孩子

满二叉树与完全二叉树

如图所见,满二叉树就是每层全满的二叉树
完全二叉树就是倒数第二层全满,最后一层靠左一侧的二叉树
为什么要单独提这两种二叉树呢?
因为这两种二叉树,是满的空间利用率高可以像堆一样,顺序存储,

由图可以看出:满二叉树与完全二叉树空间利用率很高,适合顺序存储,非完全二叉树空间利用率很低
会有大量的位置空缺,浪费空间,因此我们会采用链式存储
二叉树的性质
1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(h-1) 个结点.
2. 若规定根结点的层数为1,则深度为h的二叉树的最大结点数是 2^h - 1.
3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为n2 ,则有n0 = n2+1

二叉树的遍历
在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二
叉树结构掌握还不够深入,为了降低大家学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树
操作学习,等二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。
自己手搓一棵二叉树
c
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _data;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
BTNode* CreatBinaryTree()
{
BTNode* node1 = BuyNode(1);
BTNode* node2 = BuyNode(2);
BTNode* node3 = BuyNode(3);
BTNode* node4 = BuyNode(4);
BTNode* node5 = BuyNode(5);
BTNode* node6 = BuyNode(6);
node1->_left = node2;
node1->_right = node4;
node2->_left = node3;
node4->_left = node5;
node4->_right = node6;
return node1;
}
二叉树的遍历
大家在学习二叉树的遍历时我建议初期还是把空节点也写上
举个例子

这样对遍历就了解的很清楚下面我们展示代码实现
当然这里只是打印,没有存储他的顺序,再下一次博客,我会具体实现
二叉树的前序遍历
c
void prevorder(BTNode* root)
{
if (root == NULL)
{
printf("N ");
return;
}
printf("%d ", root->data);
prevorder(root->left);
prevorder(root->right);
}
二叉树的中序遍历
c
void Inorder(BTNode* root)
{
if (root == NULL)
{
printf("N ");
return;
}
Inorder(root->left);
printf("%d ", root->data);
Inorder(root->right);
}
二叉树的后序遍历
c
void Backorder(BTNode* root)
{
if (root == NULL)
{
printf("N ");
return;
}
Backorder(root->left);
Backorder(root->right);
printf("%d ", root->data);
}
