树(上)
1.树与树的表示:
树(Tree)是n(n≥0)个结点构成的有限集合。当n=0时,称为空树;对于任一棵非空树(n> 0),它具备以下性质:
树中有一个称为“根(Root)”的特殊结点,用 r 表示; 其余结点可分为m(m>0)个互不相交的有限集T1,T2,... ,Tm,其中每个集合本身又是一棵树,这些树称为原来树的“子树”。每个子树的根结点都与 r 有一条相连接的边,r是这些子树根结点的“父结点”。
二叉树的定义:
一棵二叉树是一个有穷的结点集合。这个集合可以为空,若不为空,则它是由根结点和称为其左子树和右子树的两个不相交的二叉树组成。可见左子树和右子树还是二叉树。
特殊二叉树:
(1).斜二叉树(Skewed Binary Tree)(也称为退化二叉树)。
(2).完美二叉树(Perfect Binary Tree)(也称为满二叉树)。
(3).一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1 ≤ i ≤ n)的结点与满二叉树中编号为 i 的结点在二叉树中的位置相同,则这棵二叉树称为“完全二叉树(Complete Binary Tree)”。
二叉树的重要性质:
(1).一个二叉树第 i 层的最大结点数为:2^(i-1),i>=1;
(2).深度为k的二叉树有最大结点总数为:2^k-1,k>=1;
(3).对任何非空的二叉树 T,若n0表示叶结点的个数、n2是度为2的非叶结点个数,那么两者满足关系n0 = n2 +1。
2.二叉树的存储结构:
(1).顺序存储结构:
非根结点(序号 i > 1)的父结点的序号是 i / 2;
结点(序号为 i )的左孩子结点的序号是 2 i(若2 i > n则没有左孩子);
结点(序号为 i )的右孩子结点的序号是 2i+1,(若2 i +1> n则没有右孩子);
3.二叉树的遍历:
树的遍历是指访问树的每个结点,且每个结点仅被访问一次。二叉树的遍历可按二叉树的构成以及访问结点的顺序分为四种方式,即先序遍历、中序遍历、后序遍历和层次遍历。
如上图:
先序遍历:根左右(ABDHIECFG)
递归实现:
void print1(struct Node *root)
{
if(root==NULL)
return ;
else
{
printf("%c",root->data);
print1(root->l);
print1(root->r);
}
};
中序遍历:左根右(HDIBEAFCG)
void print2(struct Node *root)
{
if(root==NULL)
return ;
else
{
print1(root->l);
printf("%c",root->data);
print1(root->r);
}
};
后序遍历:左右根 (HIDEBFGCA)
void print3(struct Node *root)
{
if(root==NULL)
return ;
else
{
print2(root->l);
print2(root->r);
printf("%c",root->data);
}
};
层次遍历:按照层的顺序(ABCDEFGHI)
void print(struct Node *root)
{
struct Node *a[10005];
int head,tail;
head=0;tail=0;
if(root!=NULL)
{
a[tail++]=root;
while(head!=tail)
{
printf("%c",a[head]->data);
if(a[head]->l!=NULL)
a[tail++]=a[head]->l;
if(a[head]->r!=NULL)
a[tail++]=a[head]->r;
head++;
}
}
}
4.例题:
二叉树的建立(层次遍历)
#include<stdio.h>
#include<stdlib.h>
struct Node
{
char data;
struct Node *l;
struct Node *r;
};
struct Node *creat(struct Node *head)
{
char ch;
scanf("%c",&ch);
if(ch=='#')
{
head=NULL;
}
else
{
head=(struct Node *)malloc(sizeof(struct Node));
head->data=ch;
head->l=creat(head->l);
head->r=creat(head->r);
}
return head;
}
void print(struct Node *root)
{
struct Node *a[10005];
int head,tail;
head=0;tail=0;
if(root!=NULL)
{
a[tail++]=root;
while(head!=tail)
{
printf("%c",a[head]->data);
if(a[head]->l!=NULL)
a[tail++]=a[head]->l;
if(a[head]->r!=NULL)
a[tail++]=a[head]->r;
head++;
}
}
}
int main()
{
struct Node *root,*p;
p=creat(root);
print(p);
return 0;
}