树
定义:树是结点的有限集合(n>0),它有且只有一个根结点,记为T。
特点: 除根结点T外,树的其余结点分成为m(m>0)个互不相交的集合T1,T2, …,Tm,每个集合又都是树,此时根结点T称为Ti的父结点,Ti称为T的子结点(1≤i≤m)。
概念:
度: 一个结点的子结点个数称为该结点的度
叶子或终端节点:度为0的节点
分支节点:度不为0的节点
祖先节点:根节点到该节点路径上的所有节点
子孙节点:一个节点的直接后继和间接后继
树的度: 一棵树中最大的节点度数
节点的层次: 从根节点算,根节点为第一层,其孩子为第二层
深度: 树中节点的最大层次数
森林: m棵互不相交的树的集合
二叉树
定义:由一个根节点和两棵分别称为左子树和右子树的互不相交的二叉树构成。切记!!二叉树不是树的特殊结构,两者本身是不同的树形结构,度为2的树也不一定是二叉树,二叉树可以为空,此时度为0.。
typedef struct TNode
{
type data;
struct TNode* left;
struct TNode* right;
}TNode,*Tree;
特点: 每个节点至多有两棵子树;
二叉树的子树有左右之分,且其次序不能颠倒。
性质:
1.在二叉树的第n层至多有2^(n-1)个节点
2.深度为k的二叉树至多有2^k-1个节点
3.对任何一个二叉树,如果其终端节点数为n0,度为2的节点数为n2,则n0=n2+1
4.具有n个节点的完全二叉树的深度为logn+1 (log底为2)
5.节点间关系蕴含在其存储位置中(适用于满二叉树和完全二叉树):
5.1 非根节点i的父节点序号为i/2
5.2 节点i的左孩子序号为2i: 对于总共有n个节点的树,如果2i>n,则节点无左孩子;如果2i<n,则其左孩子为2i
5.3 节点i的右孩子序号为2i+1:n个节点的树,对于节点i,如果2i+1>n,则节点无右孩子;反正则有右孩子2i+1
分类
满二叉树:二叉树上所有节点的度都为2
完全二叉树:叶节点只能出现在最下层和次下层,最下面一层的结点都集中在该层最左边的若干位置的二叉树
有序二叉树:左子树所有的节点元素小于等于根节点的元素;右子树所有的节点元素大于根节点的元素
二叉树的遍历
先序遍历:先访问根节点,再依次访问左右孩子节点
void mid_travel(Tree tree)
{
if (tree != NULL)
{
printf("%d ",tree->data);
mid_travel(tree->left);
mid_travel(tree->right);
}
}
中序遍历:先访问左孩子节点,再访问根节点,最后访问右孩子节点
void left_travel(Tree tree)
{
if (tree != NULL)
{
left_travel(tree->left);
printf("%d ",tree->data);
left_travel(tree->right);
}
}
后序遍历:先依次访问左右孩子节点,最后访问根节点
void right_travel(Tree tree)
{
if (tree != NULL)
{
right_travel(tree->right);
printf("%d ",tree->data);
right_travel(tree->left);
}
}
求树的深度
size_t max_high(Tree tree)
{
if (tree == NULL) return 0;
return 1+(max_high(tree->left)>max_high(tree->right)?max_high(tree->left):max_high(tree->right));
}
求树的节点个数
int Node_num(Tree tree)
{
if (tree != NULL)
{
return 1+Node_num(tree->left)+Node_num(tree->right);
}
else return 0;
}