二叉树的遍历
二叉树
存储结构
二叉树存储结构有静态存储(数组)和链接存储(二叉链表)方式,竞赛中一般直接采用静态存储结构。
在静态存储结构中,设left和right域存储其孩子结点下标,根节点下标一般从1开始。
对于一棵二叉树,若某节点下标为 i i i,则其父节点下标为 ⌊ i / 2 ⌋ \lfloor i/2 \rfloor ⌊i/2⌋,左子节点下标为 2 ∗ i 2*i 2∗i,右子节点下标为 2 ∗ i + 1 2*i+1 2∗i+1。
采用纯数组法进行存储二叉树,用下标进行定位子节点,非有效结点用一个占位符存储,这种方法非常适合完全二叉树。对于纯数组模拟法的二叉树,最后一个结点的下标为 2 深度 − 1 2^{深度}-1 2深度−1。
但对于非完全二叉树,会造成大量空间浪费,容易爆内存。因此对于一般的二叉树,更普适的存储方法为只存储有效节点,设置 l e f t left left和 r i g h t right right域存储其子节点下标。对应存储结构为:
struct node{
int data;
int left,right;//指针域,存储其子结点下标
}tree[n];//n:结点数
由于建树方法不同,因此需要根据不同的建树方法选择对应的存储结构。如给出一个序列表示二叉树,则非常适合直接用纯数组法;若依次按顺序给出每个结点的子节点,则适合采用结构体数组法。
遍历
先序遍历
- 纯数组版
void preorder(int i){
if(i<MAX&&tree[i]!=-1){
cout<<tree[i]<<endl;//-1充当占位符
preorder(2*i);
preorder(2*i+1);
}
}
- 结构体数组版
void preorder(int i){
if(tree[i].data!=-1){
cout<<tree[i].data<<endl;
preorder(tree[i].left);
preorder(tree[i].right);
}
}
中序遍历
- 纯数组版
void inorder(int i){
if(i<MAX&&tree[i]!=-1){
inorder(2*i);
cout<<tree[i]<<endl;
inorder(2*i+1);
}
}
- 结构体数组版
void inorder(int i){
if(tree[i].data!=-1){
inorder(tree[i].left);
cout<<tree[i].data<<endl;
inorder(tree[i].right);
}
}
后序遍历
- 纯数组版
void postorder(int i){
if(i<MAX&&tree[i]!=-1){
postorder(2*i);
postorder(2*i+1);
cout<<tree[i]<<endl;
}
}
- 结构体数组版
void postorder(int i){
if(tree[i].data!=-1){
postorder(tree[i].left);
postorder(tree[i].right);
cout<<tree[i].data<<endl;
}
}
层序遍历
- 纯数组版
void level(){
for(int i=1;i<MAX;i++)
if(tree[i]!=-1) cout<<tree[i]<<endl;
}
- 结构体数组版
void level(){
for(int i=1;i<n;i++)
if(tree[i].data!=-1) cout<<tree[i].data<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南