堆栈实现二叉树的遍历

该方式主要通过使用栈这一数据结构实现二叉树的遍历。

中序遍历

对于中序遍历而言,采用该方式的详细过程如下:

  • 遇到一个结点,就把它压栈,并遍历它的左子树
  • 当左子树遍历结束后,从栈顶弹出这个结点并访问它
  • 然后按其右指针再去中序遍历该节点
void PreOrder(BinTree BT)
{BinTree t = BT;Stack s = CreateStack();while(t || !IsEmpty(s)){while(t){Push(s, t);t = t->left;}if(!IsEmpty(s)){t = Pop(s);printf("%c", t->Data);t = t->right;}}
}

先序遍历

  • 遇到一个结点,就输出,然后把它压栈,并遍历它的左子树
  • 当左子树遍历结束后,从栈顶弹出这个结点
  • 然后按其右指针再去先序遍历该节点的左子树
// 先序非递归
void PreOrderTraversal(BinTree BT){BinTree T = BT;Stack S = CreateStack();  // 创建并初始化堆栈 Swhile(T || !IsEmpty(S)){  // 当树不为空或堆栈不空 while(T){     Push(S,T);    // 压栈,第一次遇到该结点 printf("%d",T->Data);  // 访问结点T = T->Left;   // 遍历左子树 }if(!IsEmpty(S)){  // 当堆栈不空 T = Pop(S);    // 出栈,第二次遇到该结点 T = T->Right;  // 访问右结点 }}
}

后序遍历

对于后序遍历,可以使用反序进行输出。先序的访问顺序是root,left,right,我们可以先将左右对调,则顺序变为root,right,left,然后用栈来存储,最后输出栈中的内容, 此时顺序就变为了left,right,root。

具体实现的步骤:
建立两个栈,一个用作存储root,right,left顺序的结果栈,一个用作临时栈进行先序遍历。

  • 遇到一个结点,就把它压栈,同时将该节点存到结果栈中,遍历它的右子树
  • 当右子树遍历结束后,从栈顶弹出这个结点
  • 然后按其左指针再去先序遍历该节点的左子树
  • 最后输出结果栈中的内容即可。
void PostOrder( BinTree BT )
{BinTree t = BT;Stack s = CreateStack();  //创建并初始化堆栈SStack q = CreateStack();  //创建并初始化堆栈Q,用于输出反向while( t || !IsEmpty(s) ){while(t){  //一直向右并将沿途结点压入堆栈Push(s,t);Push(q,t);//  将遍历到的结点压栈,用于反向t = t->right;}if(!IsEmpty(s)){t = Pop(s);  //结点弹出堆栈t = t->left; //转向左子树}}while( !IsEmpty(q) ){t = Pop(q);printf("%c", t->Data); //(访问)打印结点}
}

例子

针对如下二叉树的三种遍历方式进行实现:

#include<stdio.h>
#include<malloc.h>typedef struct TreeNode *BinTree;
struct TreeNode{char Data;BinTree left;BinTree right;
};//创建堆栈用于实现堆栈方式遍历二叉树
typedef struct Snode *Stack;
struct Snode{BinTree Data;Stack next;
};
Stack CreateStack();
int IsEmpty(Stack s);
void Push(Stack s, BinTree item);
BinTree Pop(Stack s);Stack CreateStack()
{Stack s;s = (Stack)malloc(sizeof(struct Snode));s->next = NULL;return s;
}
int IsEmpty(Stack s)
{return s->next == NULL;
}
void Push(Stack s, BinTree item)
{Stack tmp = (Stack)malloc(sizeof(struct Snode));tmp->Data = item;//栈顶元素是链表头结点,新入栈的链表在栈顶元素后面tmp->next = s->next;s->next = tmp;
}
BinTree Pop(Stack s)
{BinTree val;Stack tmp = s->next;val = tmp->Data;s->next = tmp->next;free(tmp);return val;
}//创建二叉树
BinTree CreateBinTree();
//插入节点
BinTree Insert(char Data);
//堆栈实现先序遍历
void PreOrder(BinTree BT);
//堆栈实现中序遍历
void InOrder(BinTree BT);
//堆栈实现后序遍历
void PostOrder(BinTree BT);BinTree Insert(char Data)
{BinTree bt = (BinTree)malloc(sizeof(struct TreeNode));bt->Data = Data;bt->left = NULL;bt->right = NULL;return bt;
}BinTree CreateBinTree()
{BinTree bt;bt = (BinTree)malloc(sizeof(struct TreeNode));bt->Data = 'a';bt->left = Insert('b');bt->right = Insert('c');bt->left->left = Insert('d');bt->left->right = Insert('f');bt->right->left = Insert('g');bt->right->right = Insert('i');bt->left->right->left = Insert('e');bt->right->left->right =Insert('h');return bt;
}//堆栈实现先序遍历
void PreOrder(BinTree BT)
{BinTree t = BT;Stack s = CreateStack();while(t || !IsEmpty(s)){while(t){Push(s, t);printf("%c", t->Data);t = t->left;}if(!IsEmpty(s)){t = Pop(s);t = t->right;}}
}void InOrder(BinTree BT)
{BinTree t = BT;Stack s = CreateStack();while(t || !IsEmpty(s)){while(t){Push(s, t);t = t->left;}if(!IsEmpty(s)){t = Pop(s);printf("%c", t->Data);t = t->right;}}
}void PostOrder( BinTree BT )
{BinTree t = BT;Stack s = CreateStack();  //创建并初始化堆栈SStack q = CreateStack();  //创建并初始化堆栈Q,用于输出反向while( t || !IsEmpty(s) ){while(t){  //一直向右并将沿途结点压入堆栈Push(s,t);Push(q,t);//  将遍历到的结点压栈,用于反向t = t->right;}if(!IsEmpty(s)){t = Pop(s);  //结点弹出堆栈t = t->left; //转向左子树}}while( !IsEmpty(q) ){t = Pop(q);printf("%c", t->Data); //(访问)打印结点}
}int main()
{BinTree bt = CreateBinTree();PreOrder(bt);printf("\n");InOrder(bt);printf("\n");PostOrder(bt);
}

堆栈实现二叉树的先序、中序及后序遍历相关推荐

  1. PAT甲级1020变体:已知二叉树层序+中序序列,求后序遍历序列

    PAT甲级1020变体:已知二叉树层序+中序序列,求后序遍历序列 题目 输入格式 输出格式 输入样例 输出样例 代码 题目 已知二叉树层序+中序序列,求后序遍历序列. 输入格式 第一行给出该二叉树的节 ...

  2. 二叉树的中序、前序、后序三种遍历图解

    二叉树是算法中的重要概念,现将中序.前序.后序三种遍历图解如下: ***站里很多帖子讲到三种遍历的顺序是逐一开展的,但是我感觉同级遍历应该是同时开展的,不知道对不对,请大牛指教~~

  3. 先序中序数组推后序数组

    二叉树遍历 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问.访问结点所做的操作依赖于具体的应用问 题. 遍历是二叉树上最重要的运算之一,是二叉树上进行其它 ...

  4. 树的遍历(中序,前序,后序)

    与只有一种逻辑遍历它们的线性数据结构(数组.链表.队列.堆栈等)不同,树可以以不同的方式遍历,常见的有中序遍历,前序遍历和后序遍历. 实现各种遍历的方法又包括: 以上图为例: 深度优先遍历:  (a) ...

  5. 已知满二叉树先序序列如何求后序序列

    如题 自用笔记 如有错误欢迎及时指正 面对仅仅知道先序序列(DLR)求后序序列(LRD),首先想到的是不可能,若对一般的二叉树而言确实无法做到,但是满二叉树的特殊性使得该命题成立!下面给出本文所用例子 ...

  6. 二叉树路径应用举例(基于非递归后序遍历)

    #include "stdafx.h" #include <iostream> #include <fstream>using namespace std; ...

  7. 二叉树的先序线索化、中序线索化、后序线索化的对比

    有一点需要注意:在先序遍历一个节点的左子树时,需要判断其ltag的值是否为0,如果为0可以正常遍历,但是,如果为1就不能进行遍历.因为ltag的值为1说明该结点的左指针指向的是它的前驱结点而不是左孩子 ...

  8. java二叉树合并_Java(树的前中后序遍历构造二叉树题型整合)前序和中序、中序和后序、前序和后序遍历序列构造二叉树算法整合归纳...

    前言 二叉树各种花里胡哨的算法题真的把我搞晕了,今天特地整理出一类有关二叉树的算法题,希望能帮助阅读到此文章的人,今后不再受此类题型的困扰. 一.题目类型 已知二叉树的两种遍历序列,请根据该序列构建二 ...

  9. 已知二叉树先序序列和中序序列,求后序序列

    回答了百度知道上的一个提问,原题是这样的: 当一棵二叉树前序序列和中序序列分别为HGEDBFCA和EGBDHFAC时,其后序序列为什么?当一棵二叉树前序序列和中序序列分别为HGEDBFCA和EGBDH ...

  10. LeetCode根据前序与中序、中序与后序,前序与后序遍历序列构建二叉树

    根据前序与中序遍历序列构建二叉树 LeetCode题目来源 1.1 题目描述 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是 ...

最新文章

  1. 2019宁波本科计算机招聘工资,@宁波人,76282!2019年度平均工资是这么多,你拖后腿了吗?...
  2. 华为云发布全新DevOps实践,大幅提升交付效率
  3. 【OpenGL】七、桌面窗口搭建 ( 导入头文件 | 桌面程序入口函数 | 注册窗口 | 创建窗口 | 显示窗口 )
  4. JavaScript类库
  5. linux工程师前景_linux运维工程师前景怎样 就业薪资待遇高吗
  6. python 2.6下 No module named sysconfig
  7. 明明还有空间,硬盘却写不进去了!
  8. java es scroll,Elasticsearch Scroll分页检索案例分享
  9. SQL 复合查询条件(AND,OR,NOT)对NULL值的处理
  10. SRP记录_20190418
  11. 安装ecshop php,如何安装ECSHOP?
  12. Jquery 实现json复杂查询等操作(jsonDB)
  13. 使用winserver2003配置DNS服务器
  14. mysql the cabinet_mysql 一个较特殊的问题:You can’t specify target table ‘wms_cabinet_form’ | 很文博客...
  15. MES系统多少钱?企业需要什么样的MES系统?
  16. insightface人脸识别代码记录(一)(数据前期准备)
  17. 单片机——点阵2(Proteus和KeilC51)
  18. java之枚举类型enum
  19. JavaScript中函数当作参数传递或当作返回值
  20. 多元回归分析--学习笔记

热门文章

  1. 【快速查看 Excel工作表sheet个数】
  2. word表格里的字被表格线遮住了怎么办
  3. 基于AT89C51单片机的并入串出乘法口诀的设计与仿真
  4. Windows结束任务管理器进程后,桌面消失如何解决?
  5. 迅雷云加速开放平台接口说明文档
  6. 利亚德助力文化与科技交融,裸眼3D显示屏打造绝美夜景
  7. iOS开发之好用的图片选择第三方TZImagePickerController
  8. 魔百盒配置服务器信息,中国移动魔百盒的使用设置?
  9. 我国鞋服企业迎来生产“大数据时代”
  10. (干货转)各大AI竞赛 Top 解决方案开源汇总+大牛经验(Kaggle,Ali,Tencent、JD、KDD Cup...)