文章目录

  • 二叉树的遍历
    • 1 先序遍历
      • 1.1 递归
      • 1.2 非递归
    • 2 中序遍历
      • 2.1 递归
      • 2.2 非递归
    • 3 后序遍历
      • 3.1 递归
      • 3.2 非递归
    • 4 层序遍历
    • 5 前中后层序完整可运行代码(C++)

二叉树的遍历

1 先序遍历

1.1 递归

先序遍历(Preorder Traversal),即根左右的顺序遍历树。递归代码如下:

void preorder(Btree T)//递归先序遍历
{if(T)  //判断结点是否为空{visit(T);   //访问根结点preorder(T->lchild);   //递归遍历左子树preorder(T->rchild);    //递归遍历右子树}
}

1.2 非递归

对于非递归的先序遍历,借助来辅助。非递归代码如下:

void preorder2(BiTree T){//非递归先序遍历InitStack(S);  //初始化栈SBiTree p = T;   //p作为遍历指针while(p || !isEmpty(S)){   //栈不空或p非空就继续循环if(p){    //一路向左  visit(p);   //访问当前结点Push(S, p); //将当期那结点入栈p = p->lchild;    //左孩子非空,就一直向左走}else{Pop(S, p);   //栈顶元素出栈p = p->rchild;  //向右子树走,p赋值为当前结点的右孩子}      }
}

2 中序遍历

2.1 递归

中序遍历(Inorder Traversal),即左根右的顺序遍历树,递归代码如下:

void inorder(BiTree T){  //递归中序遍历if(T){inorder(T->lchild);visit(T);inorder(T->lchild);}
}

2.2 非递归

对于非递归的中序遍历,借助来辅助。非递归代码如下:

void inorder2(BiTree T){ //非递归中序遍历InitStack(S);BiTree p = T;while(p || !IsEmpty(S)){if(p){Push(S, p);p = p->lchild; //左}else{visit(p);  //根Pop(S, p);p = p->rchild; //右}}
}

3 后序遍历

3.1 递归

后序遍历(Postorder Traversal),即左右根的顺序遍历树,递归代码如下:

void postorder(BiTree T){if(T){postorder(T->lchild);postorder(T->rchild);visit(T);}
}

3.2 非递归

对于非递归的后序遍历,借助来辅助。

​ 需要注意的是,后序非递归遍历算法和先序中序非递归遍历算法的思路有一点区别,后序非递归算法在visit一个结点时,需要保证左孩子与右孩子都已被访问,并且左孩子需在右孩子之前被访问(左右根)。

于是何时可以visit一个结点,就有了以下 2 种情况:

  1. 该结点的左右孩子均为空
  2. 该结点无右孩子,且左孩子已被访问 or 左右孩子存在且都已被访问

对于判断一个结点是否被访问过,我们可以定义一个指针r来进行辅助。

非递归代码如下:

void postorder2(BiTree T){   //非递归后序遍历InitStack(S);BiTNode *p = T;  //注:写成BiTree p = T;也可BiTNode *r = NULL;        //注:写成BiTree r = NULL;也可while(p || !IsEmpty(S)){if(p){Push(S, p);p = p->lchild; //左}else{GetTop(S, p);  //查看栈顶元素if(p->rchild && p->rchild != r){ //如果右孩子存在且没被访问过p = p->rchild;   //右}else{visit(p);  //根Pop(S, p);r = p;    //记录刚刚访问过的结点p = NULL;  //结点访问完,p置空以便继续回溯到其父节点进行后序遍历}}}
}

4 层序遍历

层序遍历(Level Order Traversal),即从上至下,从左到右,一层一层地访问结点:

图1 二叉树的层序遍历

对于二叉树的层序遍历,借助队列来辅助。代码如下:

void levelorder(BiTree T){InitQueue(Q);  //初始化辅助队列BiTree p;EnQueue(Q, T);    //根结点入队while(!IsEmpty(Q)){  //队列不为空则循环DeQueue(Q, p);    //队头结点出队visit(p);   //访问出队的结点if(p->lchild != NULL)  //出队结点的左孩子非空EnQueue(Q, p->lchild);   //左孩子入队if(p->rchild != NULL)    //出队结点的右孩子非空EnQueue(Q, p->rchild);   //右孩子入队}
}

5 前中后层序完整可运行代码(C++)

#include <iostream>
#include <queue>//引入队列头文件
using namespace std;typedef struct Bnode    /*定义二叉树存储结构*/
{ char data;struct Bnode *lchild,*rchild;
}Bnode,*Btree;void Createtree(Btree &T) /*创建二叉树函数*/
{//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树Tchar ch;cin >> ch;if(ch=='#')T=NULL;          //递归结束,建空树else{T=new Bnode;T->data=ch;                  //生成根结点Createtree(T->lchild);    //递归创建左子树Createtree(T->rchild);  //递归创建右子树}
}void preorder(Btree T)//先序遍历
{if(T){cout<<T->data<<"  ";preorder(T->lchild);preorder(T->rchild);}
}void inorder(Btree T)//中序遍历
{if(T){inorder(T->lchild);cout<<T->data<<"  ";inorder(T->rchild);}
}void posorder(Btree T)//后序遍历
{if(T){posorder(T->lchild);posorder(T->rchild);cout<<T->data<<"  ";}
}bool Leveltraverse(Btree T)
{Btree p;if(!T)return false;queue<Btree>Q; //创建一个普通队列(先进先出),里面存放指针类型Q.push(T); //根指针入队while(!Q.empty()) //如果队列不空{p=Q.front();//取出队头元素作为当前扩展结点livenodeQ.pop(); //队头元素出队cout<<p->data<<"  ";if(p->lchild)Q.push(p->lchild); //左孩子指针入队if(p->rchild)Q.push(p->rchild); //右孩子指针入队}return true;
}int main()
{Btree mytree;cout<<"按先序次序输入二叉树中结点的值(孩子为空时输入#),创建一棵二叉树"<<endl;Createtree(mytree);//创建二叉树cout<<endl;cout<<"二叉树的先序遍历结果:"<<endl;preorder(mytree);//先序遍历二叉树cout<<endl;cout<<"二叉树的中序遍历结果:"<<endl;inorder(mytree);//中序遍历二叉树cout<<endl;cout<<"二叉树的后序遍历结果:"<<endl;posorder(mytree);//后序遍历二叉树cout<<endl;cout<<"二叉树的层次遍历结果:"<<endl;Leveltraverse(mytree);//层次遍历二叉树return 0;
}

输入描述与示例

​ 这段代码包括创建二叉树、先序遍历、中序遍历、后序遍历和层次遍历。输入样例应该是一个字符串,其中每个字符代表一个节点的值,按照先序遍历的顺序输入。当输入字符为“#”时,表示该结点为空。

例如,对于一棵如下所示的二叉树:

    A/ \B   C/ \   \
D   E   F

输入样例应该是:ABD##E##C#F##。其中,A 是根节点,BA 的左子节点,DB 的左子节点,# 表示 D 的左子节点为空,接下来的 # 表示 D 的右子节点为空,以此类推。

运行结果

图2 代码运行结果

最新文章

  1. html5面板制作代码,HTML5绘制设备面板
  2. python中plot柱状图-Matplotlib中柱状图bar使用
  3. Windows核心编程 第四章 进程(下)
  4. 第一节、Alex 讲解 python+mysql 交互;
  5. 临近年关,修复ASP.NET Core因浏览器内核版本引发的单点登录故障
  6. 华为云 手机 电脑登录不了怎么办 账户_华为云手机能解决芯片困难,是否真的实在,来西瓜视频找答案...
  7. ArcGIS——数据库与服务备份(二、arcgis server中站点服务的备份和恢复)
  8. 将url参数转为json对象
  9. 如何把pdf转换成ezd_pdf怎么转换成word怎样编辑
  10. Linux 服务器上安装 ANSYS Fluent 2020R2
  11. eos utility中文版v3.7.0
  12. HTML5/CSS3动画应用
  13. 如何设置PPT里的表格行高等高
  14. 功率因数校正的离线式开关电源设计
  15. 多模态交互在,数智化营销服中的技术实践
  16. Go入门系列(十七) go并发之基于共享变量的并发
  17. 胡爱玲医生论中医治疗荨麻疹的优势和理念
  18. fanuc机器人基于程序号码选择(PNS)的自动运转
  19. 北理和国防科技计算机,“国防七子”实力真的非常强大吗?理科考生在他们之间该怎么做选择?...
  20. java 书 例子_刚学了java中的方法,看了书本的例子不会做,求大神做出来研究下...

热门文章

  1. 分享一些it学习网站
  2. pdfboxiText生成PDF文件格式及读取PDF文件内容的小示例--完美支持中文版
  3. AI 组队在 Dota 2 五对五团战中首次战胜人类,协作型人工智能的里程碑式突破...
  4. 《查理·芒格的智慧:投资的格栅理论》读书笔记
  5. 《浅谈Cache Memory》 学习-第四章
  6. 【近世代数学习笔记】(一)基本概念
  7. InVEST模型,掌握产水(包括水源涵养)、碳存储(包括固碳)、土壤保持、水质(氮磷)、生境质量和热岛缓解等生态系统服务评估方法,开展人类活动影响、重大工程实施的生态成效评估
  8. 电影评分数据分析python_利用Python进行数据分析(1):第2章,url、电影评分、婴儿名...
  9. STM32物联网项目-低功耗模式
  10. php mcrypt aes,简单的PHP加密/解密(Mcrypt,AES)