一、树
1、树的含义
树(Tree) 是n (n≥0)个节点 的有限集合 T,它满足两个条件 :
有且仅有一个 特定的称为根(Root)的节点 ;- 其余的节点可以分为m(m≥0)个互不相交的有限集合
T1、T2、……、Tm ,其中每一个集合又是一棵树 ,并称为其根的子树
表示方法 :树形表示法 、目录表示法 。
2、树的特点(选看)
(1)结点与度数
- 一个
节点 的子树的个数 称为该节点的度数 一棵树的度数 是指该树中节点的最大度数 度数为零 的节点 称为树叶 或终端节点 - 度数
不为零 的节点称为分支节点 - 除根节点外的
分支节点 称为内部节点 。
(2)路径与层数
- 一个节点系列k1,k2, ……,ki,ki+1, ……,kj,并满足
ki 是ki+1 的父节点 ,就称为一条从k1到kj的路径 - 路径的长度为
j-1 ,即路径中的边数 。 - 路径中前面的节点是后面节点的祖先,后面节点是前面节点的子孙。
节点的层数 等于父节点的层数加一 ,根节点的层数定义为一 。树中节点层数的最大值称为该树的高度或深度。
(3)有序树与森林
- 若树中
每个节点 的各个子树 的排列为从左到右 ,不能交换,即兄弟之间是有序的 ,则该树称为有序树 。 m(m≥0) 棵互不相交 的树的集合 称为森林 。- 树去掉根节点就成为
森林 ,森林 加上一个新的根节点 就成为树。
3、树的逻辑结构
树中任何节点都可以有零个或多个直接后继节点(子节点),但至多只有一个直接前趋节点(父节点),根节点没有前趋节点,叶节点没有后继节点 。
二、二叉树
1、二叉树的含义
二叉树 是n(n≥0) 个节点 的有限集合 或者是空集(n=0) 或者是由一个根节点以及两棵互不相交的 . 分别称为左子树 和右子树 的二叉树 组成 严格区分左孩子和右孩子 ,即使只有一个子节点也要区分左右。
2、二叉树性质
- 二叉树
第i(i≥1)层 上的节点最多 为2^(i-1) 个。 深度 为k(k≥1) 的二叉树最多有2^k-1 个节点。
满二叉树 :深度为k(k≥1) 时有2k-1 个节点的二叉树。
完全二叉树 :只有最下面两层 有度数小于2 的节点 ,且最下面一层 的叶节点 集中在最左边的若干位置上 。
具有n个节点的完全二叉树的深度为
(log2n)+1或 log2(n+1)。
3、二叉树-顺序存储
顺序存储结构 :完全二叉树节点 的编号方法 是从上到下 ,从左到右 ,根节点为1号节点 。设完全二叉树的节点数为n ,某节点编号为i 。
- 当
i>1(不是根节点) 时,有父节点 ,其编号为i/2 ; - 当
2*i≤n 时,有左孩子 ,其编号为2*i ,否则没有左孩子,本身是叶节点 ; - 当
2*i+1≤n 时,有右孩子 ,其编号为2*i+1 ,否则没有右孩子; - 当
i为奇数且不为1 时,有左兄弟 ,其编号为i-1 ,否则没有左兄弟; - 当
i为偶数且小于n 时,有右兄弟 ,其编号为i+1 ,否则没有右兄弟;
有n个节点 的完全二叉树 可以用有n+1个元素 的数组 进行顺序存储 ,节点号 和数组下标 一一对应,下标为零的元素 不用。
利用以上特性,可以从下标获得节点的逻辑关系 。不完全二叉树 通过添加虚节点 构成完全二叉树 ,然后用数组存储 ,这要浪费一些存储空间。
4、二叉树-链式存储
示意图: 结构体定义:
typedef char datatype;
typedef struct node_t
{
datatype data;
struct node_t *left_tree;
struct node_t *right_tree;
}bittree;
5、二叉树的遍历
遍历 :沿某条搜索路径周游二叉树,对树中的每一个节点 访问一次且仅访问一次 。
二叉树是非线性结构 ,每个结点有两个后继 ,则存在如何遍历即按什么样的搜索路径进行遍历的问题。
由于二叉树的递归性质,遍历算法 也是递归 的。
三种基本的遍历算法如下 :
先序序列 :先访问树根,再访问左子树,最后访问右子树;中序序列 :先访问左子树,再访问树根,最后访问右子树;后序序列 :先访问左子树,再访问右子树,最后访问树根; 示例:
6、二叉树创建与遍历C程序的实现
(1)二叉树的创建
bittree *tree_create()
{
datatype value;
bittree *r;
scanf("%c", &value);
if(value == '#')
return NULL;
r = (bittree *)malloc(sizeof(bittree));
if(r == NULL)
{
#if DEBUG
printf("bittree create error!\n");
#endif
return NULL;
}
r->data = value;
r->left_tree = tree_create();
r->right_tree = tree_create();
return r;
}
(2)前序遍历法
int preorder(bittree *r)
{
if(r == NULL)
return 0;
printf("%c ", r->data);
preorder(r->left_tree);
preorder(r->right_tree);
return 1;
}
(3)中序遍历
int inorder(bittree *r)
{
if(r == NULL)
return 0;
inorder(r->left_tree);
printf("%c ", r->data);
inorder(r->right_tree);
return 1;
}
(4)后序遍历
int backorder(bittree *r)
{
if(r == NULL)
return 0;
backorder(r->left_tree);
backorder(r->right_tree);
printf("%c ", r->data);
return 1;
}
(4)层数遍历
需要应用链表队列
int levelorder(bittree *r)
{
linkqueue lq;
if(r == NULL)
{
#if DEBUG
printf("r is NULL\n");
#endif
return 0;
}
if((lq = linkqueue_create()) == NULL)
return 0;
linkqueue_enter(lq, r);
while(!linkqueue_empty(lq))
{
r = linkqueue_out(lq);
printf("%c ",r->data);
if(r->left_tree != NULL)
linkqueue_enter(lq, r->left_tree);
if(r->right_tree != NULL)
linkqueue_enter(lq, r->right_tree);
}
puts("");
return 1;
}
三、完整程序链接
二叉树C语言程序实现
到这里就结束啦!
|