树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。
二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2的 i -1次方个结点;深度为k的二叉树至多有2^(k) -1个结点;对任何一棵二叉树T,如果其终端结点数(即叶子结点数)为n0,度为2的结点数为n2,则n0 = n2 + 1。
二叉树的链式存储结构是一类重要的数据结构,其形式定义如下:
typedef struct st
{
char data;
struct st *l,*r;
}tree;
二叉树的创建:
通过读入一个字符串,建立二叉树的算法如下:
tree *creat(tree *T)
{
char x;
scanf("%c",&x);
if(x=='#')
T=NULL;
else
{
T=(tree*)malloc(tree);
//生成根结点
T->data=x;
creat(T->l);
//构造左子树
creat(T->r);
//构造右子树
}
return T;
}
二叉树的遍历:
遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。
递归算法:
//先序遍历
void qq(tree *t)
{
if(t!=NULL)
{
printf("%d",t->data);
//访问根结点
qq(t->l);
//访问左子结点
qq(t->r);
//访问右子结点
}
}
//中序遍历
void pp(tree *t)
{
if(t!=NULL)
{
qq(t->l);
//访问左子结点
printf("%d",t->data);
//访问根结点
qq(t->r);
//访问右子结点
}
}
//后序遍历
void hh(tree *t)
{
if(t!=NULL)
{
qq(t->l);
//访问左子结点
qq(t->r);
//访问右子结点
printf("%d",t->data);
//访问根结点
}
}
<4>层次遍历
【思路】:按从顶向下,从左至右的顺序来逐层访问每个节点,层次遍历的过程中需要用队列。
扫描二维码关注公众号,回复:
2464984 查看本文章
void qq(tree *t)
{
tree p=t;
//队列
queue<tree*>queue;
//根结点入队
queue.push(p);
//队列不空循环
while(!queue.empty())
{
//队头元素出队
p=queue.front();
//访问p指向的结点
printf("%c",p->data);
//退出队
queue.pop();
//左子树不空,将左子树入队
if(p->l!=NULL)
queue.push(p->l);
//右子树不空将右子树入队
if(p->r!=NULL)
queue.push(p->r);
}
}