二叉树是一个非常重要的树形结构,它的存储结构和运算都较为简单,而树也很容易转换成二叉树,本文主要探讨二叉树的遍历,一共分为前序、中序和后序三种遍历方式,使用递归进行遍历代码简介易懂。下面先介绍递归前序遍历及非递归方式的中序和后序遍历。

二叉树遍历的定义

  1. 先序遍历。
    如果二叉树为空,则空操作;否则依次执行以下操作。
  • 访问根结点
  • 先序遍历根结点的左子树
  • 先序遍历根结点的右子树
  1. 中序遍历
    如果二叉树为空,则空操作;否则依次执行以下操作。
  • 中序遍历根结点的左子树
  • 访问根结点
  • 中序遍历根结点的右子树
  1. 后序遍历
    如果二叉树为空,则空操作;否则依次执行以下操作。
  • 后序遍历根结点的左子树
  • 后序遍历根结点的右子树
  • 访问根节点

二叉树例图
与本文定义类型不符。

二叉树的类型描述

typedef struct BTNode
{int elem;struct BTNode *left,*right;
}*BinTree;

【先序遍历】

void PreOrder(BinTree root)
{if(root!=NULL){printf("%4d",root->elem);  /*访问根结点*/PreOrder(root->left);      /*先序遍历根结点的左子树*/PreOrder(root->right);     /*先序遍历根结点的右子树*/}
}

中序遍历和后续递归遍历
在此不做过多的介绍,那就开始上非递归遍历吧。

【非递归中序遍历】
二叉树中序遍历的非递归算法的主要思想是令变量root为指向根节点的指针,从根结点开始遍历。显然,第一次遇到根结点并不进行访问,而是入栈,因为此时root所指根结点及其右子树尚未被访问,必须将root保存在栈中,以便在访问完左子树后,从栈中取出root,对其所指根结点及其右子树进行访问。在root进栈后,就中序遍历它的左子树,即把root的左孩子赋给root,沿左链走下去,直到左链为空,左子树遍历完毕,此时节点出站,把栈定元素赋给root,这是第二次遇到该节点,此时其左子树已经访问完毕,按照中序遍历的定义,访问根结点(打印该节点的信息),随后中序遍历其右子树,即把root的右孩子赋给root,重复上述过程,直至root为空栈则结束。
其大致概括为:

  1. 入栈后检测左边。出栈后检测右边。
  2. 非递归中序遍历的特点是先进栈根节点,然后在判断有没有左节点
  3. 如果有继续进栈,如果为空,出栈,出栈后判断有没有右节点
  4. 如果有右节点进栈。然后以此类推。进栈的动作是连续的(只要有左节点就一直进栈),而出栈
    的动作只有一次。因为出栈后会判断有没有右节点,如果有且该节点不为空会重复上述过程,否继续出栈。

定义栈

#define MaxSize
typedef struct
{BinTree elem[MaxSize];int top;
}SeqStack;

中序遍历非递归实现算法描述:

void InOrder(BinTree root)
{SeqStack s;s.top=-1;do{while(root!=NULL){s.top++;if(s.top>=MaxSize-1){printf("栈已经满了!\n");return ;}else{s.elem[s.top]=root;root=root->left;}}if(s.top!=-1){root=s.elem[s.top];s.top--;printf("\n%4d",root->elem);root=root->right;}}while((s.top!=-1)||(root!=NULL));}

【非递归后续遍历】

  1. 设置栈顶为-1,当根节点不为空时,进栈并设置该节点的访问次数为零,再次判断有没有左元素,如果有继续进栈。(左元素为空结束)
  2. 出栈,退出之后判断栈是否为空,不为空时取出栈顶元素。判断是否有右孩子或者被访问的次数是否为零。
  3. 如果没有右孩子且被访问次数为1时出栈。否则(也就是说有右孩子并且访问次数为零时)设置该节点的被访问次数为1.再把右孩子地址赋值给该节点。
  4. 判断该节点是否为空。不为空时进栈并设置该节点的访问次数为零。访问左元素。依次循环(结合代码)
void PostOrder(BinTree root)
{SeqStack s;s.top=-1;while(root!=NULL){s.top++;if(s.top==MaxSize-1){printf("栈已经满了!\n");printf("Error");}else{root->count=0;s.elem[s.top]=root;root=root->left;}}while(s.top!=-1){root=s.elem[s.top];if(root->right==NULL||root->count==1){printf("\n%c",root->elem);s.top--;}else if(root->right!=NULL&&root->count!=1){root->count=1;root=root->right;while(root!=NULL){s.top++;s.elem[s.top]=root;root->count=0;root=root->left;}}}
}

前序遍历:A B D E C F
中序遍历:D B E A F C
后序遍历:D E B F C A

【数据结构之二叉树排序算法】相关推荐

  1. [ 数据结构 -- 手撕排序算法第三篇 ] 希尔排序

    手撕排序算法系列之:希尔排序. 从本篇文章开始,我会介绍并分析常见的几种排序,大致包括插入排序,冒泡排序,希尔排序,选择排序,堆排序,快速排序,归并排序等. 大家可以点击此链接阅读其他排序算法:排序算 ...

  2. 数据结构-常用的排序算法

    总第123篇 好久不见哈,我终于又更新了,惊不惊喜,意不意外,哈哈哈哈.等之后会专门写一篇文章给大家汇报汇报我最近在忙什么呢,今天这篇还是接着之前的数据结构系列继续,主要讲讲数据结构里面常用的几种排序 ...

  3. 数据结构基础和排序算法

    数据结构和算法 1. 数据结构 1.1 稀疏数组 这个简单 稀疏数组即二维数组中有大量为0或同一个无效值的时候,将其压缩为只有有效数据的稀疏数组,需要使用时将其读写出来转为二维数组. public c ...

  4. 数据结构进阶 八大排序算法详解

    数据结构就是定义出某种结构:像数组结构.链表结构.树形结构等,实现数据结构就是我们主动去管理增删查改的实现函数 排序的概念 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列 ...

  5. Java数据结构第一讲-排序算法

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  6. 数据结构和常用排序算法复杂度

    1.顺序表 插入操作时间复杂度 最好O(1),最坏O(n),平均O(n) 移动结点的平均次数n/2 删除操作时间复杂度 最好O(1),最坏O(n),平均O(n) 移动结点的平均次数(n-1)/2 按值 ...

  7. Java数据结构之八大排序算法

    目录 一.排序算法的介绍 1.排序算法 2.算法时间的频度 时间频度 3.时间复杂度 4.常见的时间复杂度 5.平均时间复杂度和最坏时间复杂度 6.空间复杂度 二.冒泡排序 1.基本介绍 2.模拟冒泡 ...

  8. 值得收藏的时间复杂度速查表:数据结构操作、排序算法、图操作、堆操作

    时间复杂度速查表 这篇文章覆盖了计算机科学里面常见算法的时间和空间的大 OBig-O 复杂度. 在参加面试前,我们经常需要花费很多时间从互联网上查找各种搜索和排序算法的优劣,了节省大家的时间,我收集了 ...

  9. 数据结构的六大排序算法详解

    文章目录 一.简单排序 1.Comparable接口介绍 2.冒泡排序 3.选择排序 4.插入排序 二.高级排序 1.希尔排序 2.归并排序 3.快速排序 4.排序的稳定性 一.简单排序 在我们的程序 ...

最新文章

  1. SPFA-DFS P3385 模板 判断负环===vector为啥过不了?
  2. 【javascript基础】由demo来进阶学习闭包等概念
  3. .NET DLR 上的IronScheme 语言互操作IronScheme控制台输入中文的问题
  4. 2022-02-25
  5. SpringBoot @Configuration •@Import •@Conditional•@ImportResoure基本使用
  6. db2增加decimal类型字段小数位_05725.16.1Hive中decimal类型字段.0结尾数据显示异常问题处理...
  7. Nuxt --- 也来说说vue服务端渲染
  8. Android中添加自己的模块 【转】
  9. java递归方法分析
  10. openwrt路由器进入安全模式
  11. 【编程题目】寻找丑数
  12. 【UVA129】Krypton Factor(回溯+在回溯法的基础上判断一个字符串是否有相邻的重复子串(后缀))
  13. 实现光标放置图片的位置放大图片
  14. 操作系统课堂笔记(4)进程管理之多道程序设计和进程
  15. Python实战,截图识别文字,过万使用量版本?
  16. js代码在调试状态执行正确,但是正常使用时没有反应
  17. iphone或者ipad上安装自己打包的ipa文件
  18. html absolute溢出,position:absolute溢出处理
  19. ubuntu18.04 快速搭建 Hyperledger Fabric超级账本框架
  20. [linux] linux sed命令删除一行/多行

热门文章

  1. 如何在Windows 10 1709版本中保存锁屏壁纸
  2. MySQL必知必会 MySQL Administrator工具下载地址
  3. vscode ImportError: No module named xxx
  4. 浅谈JCenter即将被停止服务的事件
  5. 【Linux基础】Linux下查看硬件配置
  6. 关于修改vue项目的favicon.ico图标
  7. 保险业务与系统——保险基础知识——风险与风险管理
  8. JavaSE-第10章【基础API与常见算法】
  9. AGV机器人安全传感器主要供应商
  10. error: passing xxx as 'this' argument of xxx discards qualifiers的解决办法