数据结构之---树(三)---四种树的遍历

本文详细介绍了二叉树的四种遍历方式:先序、中序、后序和层序遍历,解释了每种遍历的特点及应用场景,包括文件系统输出、关键字排序、树高度计算和层序遍历的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树的遍历常见的有先序,中序,后序,层序遍历,它们各有用处。这里以二叉树为例。

给出树的结构为:

typedef struct node *ptrnode;
typedef struct node *tree;
struct node
{
int element;
ptrnode lchild;
ptrnode rchild;
};

先序遍历常常用于打印文件输出等,特别是文件系统中,因为它可以利用节点深度信息,有层次的打印出一个文件系统的结构出来。

void preorder_travel(tree T)
{
if(T!=NULL)
{
visit(T);
preoder_travel(T->lchild);
preoder_travel(T->rchild);
}
}
而中序遍历在二叉查找树中可以很方便的解决关键字排序输出的问题,注意到的是利用二叉查找树可以将一个输入序列,在时间复杂度为O(NlogN)上建立成为一棵二叉查找树,然后打印输出将花费O(N)。

/*中序遍历,在二叉查找树中,这种遍历能够很容易解决关键字排序输出的问题*/
void midorder_travel(tree T)
{
if(T!=NULL)
{
midorder_travel(T->lchild);
visit(T);
midorder_travel(T->rchild);
}
}
后序遍历则常常用于计算数值中,比如我们想计算树的高度,其一个普适的算法描述为:

void lastorder_travel(tree T)
{
if(T!=NULL)
{
lastoeder_travel(T->lchild);
lastorder_travel(T->rchild);
visit(T);
}
}
如果我们用于计算一棵树的高度,则有:

/*计算高度*/
int height(tree T)
{
if(T==NULL)
return -1;
else
return 1+max(height(T->lchild),height(T->rchild));
}
注意到在这些算法中我们都要小心的处理空的情况,这种小心在递归中尤其重要。

最后便是层序遍历了,与前三种遍历不同的是,它并不能利用前面那种递归思想了,因为递归中栈的使用必然会使得这种同一层的打印输出变得不可能。一个显而易见的思路是使用队列,第一次的时候将首节点入列,然后我们利用一个循环,当队列不为空时,我们就出队进行操作,并把这个出队元素的所有孩子都入队。根据队列FIFO的特性,便能够实现层序遍历了。

*层序遍历*/
/*与前三种不同,栈已经不适合了,应该采用队列,当然就不是递归了*/
void level_travel(tree T,queue Q)
{
Q.Enqueue(T);
while(!is_empty(Q))
{
ptrnode temp;
temp=Q.Dequeue();
visit(temp);
if(temp->lchild!=NULL)
Q.Enqueue(temp->lchild);
if(temp->rchild!=NULL)
Q.Enqueue(temp->rchild);
}
}
注意到前面几个操作的时间复杂度都是O(N),因为我们对每个节点都进行了一次访问,而每次访问的操作时间都是常数时间,所以时间复杂度便是O(N)了。这个需要特别注意,很多时候我们一提到二叉树便会不假思索的哦O(logN),这是不正确的,具体问题具体分析,不要一概而论。给自己提个醒。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值