树
树由根结点和若干颗子树构成。每个元素称之为节点,最顶部节点成为根节点,底部没有子节点的节点称为叶子节点,如下图所示
结点的度:一个结点含有的子结点的个数称为该结点的度
兄弟结点:具有相同父结点的结点互称为兄弟结点
树的高度或深度:树中结点的最大层数
无序树:树中任意节点的子结点之间没有顺序关系,这种树称为无序树,也称为自由树
有序树:树中任意节点的子结点之间有顺序关系,这种树称为有序树;
二叉树:每个节点最多含有两个子树的树称为二叉树;如下图所示
完全二叉树:叶子结点只能出现在最下层和次下层(也就意味着除了最后一层,其他所有节点均含有两个子树),且最下层的叶子结点集中在树的左部,如下图所示
满二叉树:叶节点除外的所有节点均含有两个子树的树被称为满二叉树,如下图所示
哈夫曼树(最优二叉树):带权路径最短的二叉树称为哈夫曼树或最优二叉树;后续会介绍
二叉树树的遍历
上面介绍了树与二叉树的概念,其实实际比较常用的就是二叉树了,下面介绍一下二叉树的遍历(遍历代码在线索二叉树代码中)
二叉树的遍历分为前序、中序、后续遍历,均以递归或者循环方式从根节点开始向下遍历,只是优先获取节点的顺序不同
节点数据结构
typedef struct Tree {
int data;
struct Tree *lChild, *rChild;
} LSTree;
前序遍历
前序遍历是以中左右的方式遍历,即根节点在前
void front(LSTree *node) {
if (node) {
printf("%d\t", node->data);
if (node->ltag == 0) f(node->lchild);
if (node->rtag == 0) f(node->rchild);
}
}
中序遍历
后序遍历是以左中右的方式遍历,即根节点在中
void middle(LSTree *node) {
if (node) {
if (node->ltag == 0) m(node->lchild);
printf("%d\t", node->data);
if (node->rtag == 0) m(node->rchild);
}
}
后序遍历
后序遍历是以左右后的方式遍历,即根节点在后
void behind(LSTree *node) {
if (node) {
if (node->ltag == 0) b(node->lchild);
if (node->rtag == 0) b(node->rchild);
printf("%d\t", node->data);
}
}