0引言
树的算法关键在于递归的思想。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/feeeb3d4021b76f65a875aab21595fdf.png)
1树的相关术语
术语 | 意义 |
---|---|
结点(节点) | 包含数据域和指针域的一个结构 |
结点的度 | 结点拥有的子树数目 |
叶子结点(终端) | 度为0的结点 |
分支结点(非终端) | 度不为0的结点或有子树的结点 |
树的度 | 树内各结点的度的最大值 |
子结点(直接后继结点) | 与当前结点直接相连的下一层结点 |
父节点(直接前驱结点) | 与当前结点直接相连的上一个结点 |
祖先结点(前驱结点) | 从根节点到当前结点途径的所有结点 |
子孙结点(后继结点) | 当前结点的子树上的所有结点 |
兄弟结点 | 父节点相同的所有结点 |
堂兄弟结点 | 同一层级的所有结点 |
结点的层次(深度) | 结点在第几行就是它的层次,根节点为1 |
树的高度(深度) | 树的结点的最大层次 |
有序树 | 同一结点的所有子树,从左至右规定次序 |
无序树 | 结点的子树不分先后次序 |
森林 | m棵不相交树的集合 |
- 根节点没有父节点,其他结点有且只有一个父节点。
- 祖先结点包含父节点。
- 树的度是所有结点度的最大值,即所有结点的子节点的个数的最大值
- 二叉树是有序树,即其左、右子树不能交换位置;即使只有一棵子树也要区分是左子树还是右子树。结点都相同,交换左、右子树后,即为另一棵二叉树。
- 在满二叉树最下一层从右到左依次连续去掉若干个结点的二叉树称为完全二叉树
有序或无序,针对的是树这个结构,不是存储的数据。
2二叉树的C语言实现
二叉树的二叉链表表示
typedef struct blNode
{
elementType data; //存放元素数据
//左、右孩子结点(子树根)指针。
struct blNode *lchild, *rchild;
} btNode, *BiTree;
二叉树的遍历
先序遍历
遍历结果:D, L, R
void preTraverse(btNode *T)
{
if(T)
{
cout<<T->data<<" "; //访问根结点。打印当前结点元素值,替代visit(T)函数
preTraverse(T->lChild); //先序遍历左子树
preTraverse(T->rChild); //先序遍历右子树
}
}
中序遍历
遍历结果:L, D, R
void inTraverse(btNode *T)
{
if(T)
{
inTraverse(T->lChild); //中序遍历左子树
cout<<T->data<<" "; //访问根结点。打印当前结点元素值,替代visit(T)函数
inTraverse(T->rChild); //中序遍历右子树
}
}
后序遍历
遍历结果: L, D, R
void postTraverse(btNode *T)
{
if(T)
{
postTraverse(T->lChild); //后序遍历左子树
postTraverse(T->rChild); //后序遍历右子树
cout<<T->data<<" "; //访问根结点。打印当前结点元素值,替代visit(T)函数
}
}
已知中序序列和后序序列,或中序序列和先序序列,可以唯一的还原一棵二叉树;
而已知先序序列和后序序列不能唯一还原二叉树。
3树的应用
表达式树:用二叉树来记录表达式,通过三种遍历方式可以输出表达式的中缀记法和后缀记法。
二叉查找树:对于树中的所有结点,它的左子树中所有关键字值小于该结点的关键字值,而它的右子树中所有关键字值大于该结点的关键字值。