树
树型结构是一类重要的非线性数据结构。其中以树和二叉树最为常用只管看来,树是以分支关系的层次结构。树结构时在客观结构中广泛存在的,如人类社会的族谱和各种社会组织机构都可用树来形象表示。树在计算机领域中也得到广泛应用,如在编译程序时,可用树来表示源程序的语法结构。
树的定义和基本术语
树(Tree)是n(n≥0)个结点的有限集。在任意一颗非空树中:
(1)有且仅有一个特定的称为根的结点;
(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree).
二叉树的定义
二叉树(Binary Tree)是另一种树型结构,它的特点是每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树的性质
性质一 在二叉树的第i层上至多有
2
i
−
1
\quad2^{i-1}
2i−1 (i ≥ 1)个结点。
性质二 深度为k的二叉树至多有
2
k
−
1
\quad2^{k}-1
2k−1 (k≥1)个结点。
性质三 对任何一颗二叉树T,如果其终端结点为
n
0
\quad n_0
n0,度为二的结点数为
n
2
\quad n_2
n2,则
n
0
\quad n_0
n0 =
n
2
\quad n_2
n2 + 1。
性质四 具有n个结点的完全二叉树的深度为[
l
o
g
2
n
\quad log_{2}n
log2n]+1。
性质五 如果对一棵有n个结点的完全二叉树(其深度为
[
l
o
g
2
n
\quad log_{2}n
log2n]+1) 的结点按层序编号(从第1层到第[
l
o
g
2
n
\quad log_{2}n
log2n]+1 层,每层从左到右),则对任一结点i(1 ≤ i ≤ n),有
(1) 如果i = 1,则结点 i 是二叉树的根,无双亲;如果 i > 1,则其双亲是结点[i / 2]。
(2)如果2i > n,则结点 i 无左孩子(结点 i 为叶子结点);否则其左孩子是结点 2i,右孩子为结点 2i + 1。
*符号[ x ]表示不大于 x 的最大正整数。
二叉树的基本操作
二叉树的定义
typedef struct BiTNode {
TElemType data;
int treenu;
struct BiTNode *lchild, *rchild;
struct BiTNode * next;
} BiTNode, *BiTree;
二叉树的建立
Status InitBiTree(BiTree *T)//构造空二叉树
{
*T = NULL;
}
Status CreateBTree1(BiTree *T, char* temp)//构造二叉树(整体输入)
{
char x = temp[i];
if(temp[i] == NULL || temp[i] == '\0')
return 0;
if (temp[i] == '#'){
*T = NULL;
}
else
{
(*T) = (BiTree)malloc(sizeof(BiTNode)); //动态申请内存
if (!*T)
{
printf("内存申请失败\n");
return 0;
}
i++;
CreateBTree1(&(*T)->lchild, &temp[0]); //构造左子树
(*T)->data = x;
i++;
CreateBTree1(&(*T)->rchild, &temp[0]); //构造右子树
}
return 1;
}
二叉树的输出
void PreOrderTraverse(BiTree *T)//先序遍历
{
if (*T)
{
printf("%c ", (*T)->data); //输出双亲结点
PreOrderTraverse(&(*T)->lchild); //遍历左孩子
PreOrderTraverse(&(*T)->rchild); //遍历右孩子
}
}
void InOrderTraverse(BiTree *T)//中序遍历
{
if (*T)
{
InOrderTraverse(&(*T)->lchild); //遍历左孩子
printf("%c ", (*T)->data); //输出双亲结点
InOrderTraverse(&(*T)->rchild); //遍历右孩子
}
}
void UnOrderTraverse(BiTree *T) //后序遍历
{
if (*T)
{
UnOrderTraverse(&(*T)->lchild); //遍历左孩子
UnOrderTraverse(&(*T)->rchild); //遍历右孩子
printf("%c ", (*T)->data); //输出双亲结点
}
}
获得各种结点以及树叶的个数
int GetBiTNodeNumber(BiTree *T)//获得二叉树节点个数
{
if((*T) == NULL)
return 0;
else
{
int left, right, all;
left = GetBiTNodeNumber(&(*T)->lchild);
right = GetBiTNodeNumber(&(*T)->rchild);
all = left + right + 1;
return all;
}
}
int Get1BiTNodeNumber(BiTree *T)//获得单节点个数
{
if((*T) == NULL)
return 0;
if(((*T)->lchild == NULL &&(*T)->rchild != NULL)||((*T)->lchild != NULL &&(*T)->rchild == NULL))
{
int left, right, all;
left = Get1BiTNodeNumber(&(*T)->lchild);
right = Get1BiTNodeNumber(&(*T)->rchild);
all = left + right + 1;
return all;
}
else
{
int left, right, all;
left = Get1BiTNodeNumber(&(*T)->lchild);
right = Get1BiTNodeNumber(&(*T)->rchild);
all = left + right;
return all;
}
}
int GetleavesNumber(BiTree *T)//获得树叶个数
{
if((*T) == NULL)
return 0;
if((*T)->lchild == NULL && (*T)->rchild == NULL)
return 1;
else
{
int left, right, all;
left = GetleavesNumber(&(*T)->lchild);
right = GetleavesNumber(&(*T)->rchild);
all = left + right;
return all;
}
}