二叉树的遍历

二叉树

存储结构

二叉树存储结构有静态存储(数组)和链接存储(二叉链表)方式,竞赛中一般直接采用静态存储结构。

在静态存储结构中,设left和right域存储其孩子结点下标,根节点下标一般从1开始。

对于一棵二叉树,若某节点下标为 i i i,则其父节点下标为 ⌊ i / 2 ⌋ \lfloor i/2 \rfloor i/2,左子节点下标为 2 ∗ i 2*i 2i,右子节点下标为 2 ∗ i + 1 2*i+1 2i+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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值