数据结构与算法 二叉树的遍历

本文详细介绍了二叉树的四种遍历方法:先序、中序、后序和层序遍历。每种遍历方法通过示意图和代码实现的方式进行了清晰的解释,包括递归和非递归的解决方案。这些遍历方法的核心在于如何将二维结构的二叉树线性化处理,以便于访问所有节点。同时,文中还总结了遍历过程中节点的访问顺序和存储结构的选择,如堆栈和队列的应用。

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

先序遍历

遍历过程

  1. 访问根节点
  2. 先序遍历其左子树
  3. 先序遍历其右子树

示意图

先序遍历二叉树

代码实现

void PreOrderTraversal(BinTree BT)
{
  // 判断节点是否为空节点
  if(BT){
    //  这是要对节点中数据进行的操作
    printf("%d", BT->Data);
    //  递归遍历子节点
    PreOrderTraversal(BT->Left);
    PreOrderTraversal(BT->Right);
  }
}

中序遍历

遍历过程

  1. 中序遍历其左子树
  2. 访问根节点
  3. 中序遍历其右子树

示意图

在这里插入图片描述

代码实现

void InOrderTraversal(BinTree BT){
  if(BT){
    InOrderTraversal(BT->Left);
    print("%d", BT->Data);
    InOrderTraversal(BT->Right);
  }
}

后序遍历

遍历过程

  1. 后序遍历其为左子树
  2. 后序遍历其为右子树
  3. 访问根节点

示意图

在这里插入图片描述

代码实现

void PostOrderTraversal(BinTree BT){
  if(BT){
    PostOrderTraversal(BT->Left);
    PostOrderTraversal(BT-Right);
    printf("%d", BT->Data);
  }
}

先序、中序和后序遍历总结

  • 先序、中序和后序遍历过程:遍历过程中经过节点的路线一样,只是访问各个节点的时机不同
  • 在下图↓中,入口到出口的曲线上用 三种符号分别标记出了先序中序后序访问各节点的时刻
    在这里插入图片描述

中序遍历非递归遍历算法

遍历过程

  • 遇到一个节点,就把它压栈,并去遍历它的左子树
  • 左子树遍历结束后,从栈顶弹出这个节点并访问它
  • 然后按其右指针再去中序遍历该节点的右子树

代码实现

void InOrderTraversal(BinTree BT){
  BinTree T = BT;
  //  创建并初始化堆栈 S*
  Stack S = CreatStack(MaxSize);
  while(T || !IsEmpty(S)){
    //  一直向左并将沿途结点压入堆栈
    while(T){
      Push(S, T);
      T = T->Left;
    }
    if(!IsEmpty(S)){
      //  结点弹出堆栈
      T = Pop(S);
      //  (访问)打印结点
      printf("%d", T->Data);
      //  转向右子树
      T = T->Right;
    }
  }
}

层序遍历

遍历过程

  1. 从队列中取出一个元素
  2. 访问该元素所指的结点
  3. 若该元素所指结点的左、右子结点非空,则将其左、右子结点的指针顺序入队

示意图

在这里插入图片描述

代码实现

void LevelOrderTraversal(BinTree BT){
  Queue Q;
  BinTree T;
  //  若是空树则直接返回
  if(!BT) return;
  //  创建并初始化队列 Q
  Q = CreatQueue(MaxSize);
  AddQ(Q, BT);
  while(!IsEmptyQ(Q)){
    T = DeleteQ(Q);
    //  访问取出队列的结点
    printf("%d", T->Data);
    if(T->Left) Add(Q, T->Left);
    if(T->Right) Add(Q, T->Right);
  }
}

总结

二叉树遍历的核心问题:二维结构的线性化

  • 从结点访问其左、右子结点
  • 访问左子结点后,右子结点怎么办?
  1. 需要一个存储结构保存暂时不访问的结点
  2. 存储结构:堆栈、队列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Huber Wong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值