1. 树的概念
主要的定义:
节点的度:一个节点含有的子树的个数称为该节点的度;如上图:A的为6
叶节点或终端节点:度为0的节点称为叶节点;如上图:B,C,H,I等节点为叶节点
分支节点或非终端节点:度不为0的节点;如上图:D,E,F,G等节点为分支节点
父节点或者双亲结点节点:若一个节点含有子节点,则这个节点成为其子节点的父节点
子节点或孩子节点:一个节点含有的子树的根节点称为该节点的子节点
兄弟节点:具有相同父节点的节点互称为兄弟节点
树的度:一棵树中最大节点的度称为树的度
节点的层次:从根开始定义起,根为第一层,根的子节点为第二层
树的高度或深度:树中结点的最大层次
节点的祖先:从根到该结点所经分支上的所有节点
子孙:以某节点为根的子树中任一节点都称为该节点的子孙
森林:由m(m>0)颗互不相交的多棵树的集合称为森林
2. 对各知识点的进一步画图解析:
- 节点的度
- 叶节点(终端节点)
- 分支节点(非终端节点)
- 父节点(双亲节点)
- 子节点(孩子节点)
- 兄弟节点
- 树的高度
- 节点的高度:从下往上数
- 堂兄弟节点
- 节点的祖先
- 子孙
3. 二叉树概念及结构
3.1概念
一棵二叉树是节点的有限集合,该集合或者为空,或者是由一个根节点加上两颗别称为左子树和右子树的二叉树组成。
3.2 二叉树的特点:
1. 每个节点最多有两颗子树,即二叉树不存在度大于2的节点。
2. 二叉树的子树有左右之分,其子树的次序不能颠倒。
3.3 链式二叉树存储的概念
二叉树的链式存储结构是指:用链表来表示一颗二叉树,即用链来指示元素的逻辑关系。
通常的方式是链表中每个节点由三个域组成,数据域和左右指针域,左右指针分别用来给出该节点左孩子和右孩子所在的链接点的存储地址。
链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,后面课程学到高阶数据结构如红黑树等会用到三叉链。
3.4 二叉树的遍历
学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。访问节点所做的操作依赖于具体的应用问题。遍历时二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。
- 前序遍历(Preorder Traversal)
亦称先序遍历,访问根结点的操作发生在遍历其左右子树之前。
- 中序遍历(Inorder Traversal)
访问根节点的操作发生在遍历其左右子树之间
- 后序遍历(Postorder Traversal)
访问根节点的操作在遍历其左右子树之后。
由于被访问的节点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历
- 层序遍历(LevelOrder)
设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
4. 二叉树功能的实现
- 二叉树结构定义(struct BinaryTreeNode)
代码实现:
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
- 二叉树节点的创建(CreatBinaryTree)
BTNode* BuyNode(BTDataType x)//树中一个节点的创建
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
if (node == NULL)
{
perror("malloc fail");
return NULL;
}
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
-
二叉树的前序遍历函数(PrevOrder)
递归不可能一直调用函数,因为这个过程一直在创建栈帧,即使栈再大,也会栈溢出。所以肯定会回归,回归的本质就是销毁栈帧。
递归是由两个部分构成:
1. 子问题
2. 返回条件
代码实现:
void PrevOrder(BTNode* root)
{
if (root == NULL)
{
printf("N ");
return;
}
printf("%d ", root->data);
PrevOrder(root->left);
PrevOrder(root->right);
}