#include "stdafx.h"
#include <iostream>
#include <stack>
#include <queue>
#include <Windows.h>
using namespace std;typedef struct _Node
{int data;struct _Node *left;struct _Node *right;bool isVisit;        //用于后序非递归遍历,表示节点是否可以访问
    _Node(){data = 0;left = NULL;right = NULL;isVisit = false;}
}Node, *PNode;//****************二叉树的递归建造********************
//约定:输入0表示该节点的子树为NULL
void RecurCreate(PNode pRoot)
{int data;cin>>data;if (0 != data){pRoot = new Node;pRoot->data = data;RecurCreate(pRoot->left);RecurCreate(pRoot->right);}
}//假定二叉树如下图所示,利用前序和中序、后序与中序可以唯一确定一棵二叉树的原理
//                       1
//                     /   \
//                    2     3
//                  / \     / \
//                 4   5   6   7
//               / \  /
//              8   9 10const int MAX_NUM = 10;                             //二叉树的节点数
int pre[MAX_NUM] = {1, 2, 4, 8, 9, 5, 10, 3, 6, 7}; //前序遍历的数组
int mid[MAX_NUM] = {8, 4, 9, 2, 10, 5, 1, 6, 3, 7}; //中序遍历的数组
int post[MAX_NUM] = {8, 9, 4, 10, 5, 2, 6, 7,3, 1}; //后序遍历的数组//获取前序数组的data在中序数组的索引
int GetPositionInMid(int data)
{for (int i = 0; i < MAX_NUM; i++){if (mid[i] == data){return i;}}
}//利用前序和中序可以唯一确定一棵二叉树
//参数说明
// pRoot   —— 需要建造节点的指针引用
// iPre    —— 表示pRoot节点的左子树(右子树)在前序数组的第一个索引
// iMid    —— 表示pRoot节点的左子树(右子树)在中序数组的第一个索引
// length  —— 表示pRoot节点的左子树(右子树)的长度
void PreAndMidRecurCreate(PNode &pRoot, int iPre, int iMid, int length)
{if (length <= 0){return;}pRoot = new Node;pRoot->data = pre[iPre];int pos = GetPositionInMid(pre[iPre]);PreAndMidRecurCreate(pRoot->left, iPre + 1, iMid, pos - iMid);PreAndMidRecurCreate(pRoot->right, iPre + (pos - iMid) + 1, pos + 1, length - (pos - iMid) - 1);
}//利用后序和中序可以唯一确定一棵二叉树
//参数说明
// pRoot   —— 需要建造节点的指针引用
// iPost   —— 表示pRoot节点的左子树(右子树)在后序数组的第一个索引
// iMid    —— 表示pRoot节点的左子树(右子树)在中序数组的第一个索引
// length  —— 表示pRoot节点的左子树(右子树)的长度
void PostAndMidRecurCreate(PNode &pRoot, int iPost, int iMid, int length)
{if (length <= 0){return;}pRoot = new Node;pRoot->data = post[iPost];int pos = GetPositionInMid(post[iPost]);PostAndMidRecurCreate(pRoot->left, iPost - 1 - (length - (pos - iMid) - 1), iMid, pos - iMid);PostAndMidRecurCreate(pRoot->right, iPost - 1, pos + 1, length - (pos - iMid) - 1);
}//****************二叉树的递归遍历********************//前序递归遍历
void PreRecurTraversal(PNode pRoot)
{if (NULL != pRoot){cout<<pRoot->data<<'\t';PreRecurTraversal(pRoot->left);PreRecurTraversal(pRoot->right);}
}//中序递归遍历
void MidRecurTraversal(PNode pRoot)
{if (NULL != pRoot){MidRecurTraversal(pRoot->left);cout<<pRoot->data<<'\t';MidRecurTraversal(pRoot->right);}
}//序后递归遍历
void PostRecurTraversal(PNode pRoot)
{if (NULL != pRoot){PostRecurTraversal(pRoot->left);PostRecurTraversal(pRoot->right);cout<<pRoot->data<<'\t';}
}//****************二叉树的非递归遍历********************//第一种前序非递归遍历
void PreTraversalOne(PNode pRoot)
{PNode pTree = pRoot;stack<PNode> s;while (!s.empty() || NULL != pTree){while (NULL != pTree){cout<<pTree->data<<'\t';s.push(pTree);pTree = pTree->left;}if (!s.empty()){pTree = s.top();s.pop();pTree = pTree->right;}}
}//第二种前序非递归遍历
void PreTraversalTwo(PNode pRoot)
{PNode pTree = pRoot;stack<PNode> s;s.push(pTree);while (!s.empty()){pTree = s.top();cout<<pTree->data<<'\t';s.pop();if (NULL != pTree->right) //1、右子树进栈
        {s.push(pTree->right);}if (NULL != pTree->left) //2、左子树进栈
        {s.push(pTree->left);}}
}//中序非递归遍历
void MidTraversal(PNode pRoot)
{PNode pTree = pRoot;stack<PNode> s;while (!s.empty() || NULL != pTree){while (NULL != pTree){s.push(pTree);pTree = pTree->left;}if (!s.empty()){pTree = s.top();cout<<pTree->data<<'\t';s.pop();pTree = pTree->right;}}
}//后序非递归遍历
void PostTraversal(PNode pRoot)
{PNode pTree = pRoot;stack<PNode> s;while (!s.empty() || NULL != pTree){while (NULL != pTree){s.push(pTree);pTree = pTree->left;}if (!s.empty()){pTree = s.top();if (pTree->isVisit){cout<<pTree->data<<'\t';s.pop();pTree = NULL;}else{pTree->isVisit = true;pTree = pTree->right;}}}
}//层序非递归遍历——用队列,注意与第二种非递归前序遍历的区别
void LevelTraversal(PNode pRoot)
{PNode pTree = pRoot;queue<PNode> q;q.push(pTree);while (!q.empty()){pTree = q.front();q.pop();cout<<pTree->data<<'\t';if (NULL != pTree->left)  //1、左子树进队列
        {q.push(pTree->left);}if (NULL != pTree->right) //2、右子树进队列
        {q.push(pTree->right);}}
}//辅助函数,设置控制台的颜色
void SetConsoleTextColor(WORD dwColor)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);if (INVALID_HANDLE_VALUE == handle){return;}SetConsoleTextAttribute(handle, dwColor);
}int _tmain(int argc, _TCHAR* argv[])
{PNode pRoot1 = NULL;PNode pRoot2 = NULL;cout<<endl<<"******************根据前序和中序建造二叉树********************"<<endl<<endl;PreAndMidRecurCreate(pRoot1, 0, 0, MAX_NUM);SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);cout<<endl<<"******************层序遍历二叉树********************"<<endl<<endl;LevelTraversal(pRoot1);SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);cout<<endl<<"******************递归遍历二叉树********************"<<endl<<endl;cout<<endl<<"       **********前序递归遍历二叉树**********"<<endl<<endl;PreRecurTraversal(pRoot1);cout<<endl<<"       **********中序递归遍历二叉树**********"<<endl<<endl;MidRecurTraversal(pRoot1);cout<<endl<<"       **********后序递归遍历二叉树**********"<<endl<<endl;PostRecurTraversal(pRoot1);SetConsoleTextColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);cout<<endl<<"******************根据后序和中序建造二叉树********************"<<endl<<endl;PostAndMidRecurCreate(pRoot2, MAX_NUM - 1, 0, MAX_NUM);SetConsoleTextColor(FOREGROUND_GREEN | FOREGROUND_INTENSITY);cout<<endl<<"******************非递归遍历二叉树********************"<<endl<<endl;cout<<endl<<"       **********前序非递归遍历二叉树**********"<<endl<<endl;PreTraversalOne(pRoot2);cout<<endl;PreTraversalTwo(pRoot2);cout<<endl<<"       **********中序非递归遍历二叉树**********"<<endl<<endl;MidTraversal(pRoot2);cout<<endl<<"       **********后序非递归遍历二叉树**********"<<endl<<endl;PostTraversal(pRoot2);return 0;
}

输出效果如图所示

二叉树的建造、递归与非递归遍历相关推荐

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

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

  2. 遍历二叉树的各种操作(非递归遍历)

    先使用先序的方法建立一棵二叉树,然后分别使用递归与非递归的方法实现前序.中序.后序遍历二叉树,并使用了两种方法来进行层次遍历二叉树,一种方法就是使用STL中的queue,另外一种方法就是定义了一个数组 ...

  3. 二叉树的几种递归和非递归式遍历:

    二叉树的几种递归和非递归式遍历: 1 #include <fstream> 2 #include <iostream> 3 4 using namespace std; 5 6 ...

  4. 分别用递归和非递归方式实现二叉树先序、中序和后序遍历(java实现)

    分别用递归和非递归方式实现二叉树先序.中序和后序遍历 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点.我们约定:先序遍历顺序 为根.左.右;中序遍历顺序为左.根.右;后序遍历顺序为左 ...

  5. 转载:二叉树的前中后和层序遍历详细图解(递归和非递归写法)

    二叉树的前中后和层序遍历详细图解(递归和非递归写法) Monster_ii 2018-08-27 17:01:53 50530 收藏 403 分类专栏: 数据结构拾遗 文章标签: 二叉树 前序 中序 ...

  6. 九十五、二叉树的递归和非递归的遍历算法模板

    @Author:Runsen 刷Leetcode,需要知道一定的算法模板,本次先总结下二叉树的递归和非递归的遍历算法模板. 二叉树的四种遍历方式,前中后加上层序遍历.对于二叉树的前中后层序遍历,每种遍 ...

  7. 二叉树层序遍历递归与非递归_二叉树基础(1)-构建和遍历(递归和非递归)...

    二叉树的构建有2种方式:1.直接输入数字.2.根据两种顺序来判断另外一中顺序(后面会提到) 这里分享第一种构建方式,二叉树的前中后三种遍历方式(递归和非递归版本),和二叉树的层次遍历. 见代码demo ...

  8. 二叉树的遍历:先序 中序 后序遍历的递归与非递归实现及层序遍历

    二叉树的定义:一种基本的数据结构,是一种每个节点的儿子数目都不多于2的树 树节点的定义如下: // 树(节点)定义 struct TreeNode {int data; // 值TreeNode* l ...

  9. 左神算法:分别用递归和非递归方式实现二叉树先序、中序和后序遍历(Java版)

    本题来自左神<程序员代码面试指南>"分别用递归和非递归方式实现二叉树先序.中序和后序遍历"题目. 题目 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点 ...

  10. 二叉树创建及遍历算法(递归及非递归)(转)

    //二叉树处理头文件 //包括二叉树的结构定义,二叉树的创建,遍历算法(递归及非递归), /* 作者:成晓旭 时间:2001年10月7日(18:49:38-20:00:00) 内容:完成二叉树创建,二 ...

最新文章

  1. mysql piress_由MySql漏洞导致电脑被入侵(特征为新增加名为piress的帐户)所想到的...
  2. 启帆工业机器人综合收入如何_发那科工业机器人ROBOGUIDE如何更方便的查看机器人报警日志...
  3. 对css float 浮动的学习心得
  4. vue 导入element-ui css报错解决方法
  5. 【ArcGIS Pro微课1000例】0002:ArcGIS Pro 2.5二三维联动显示
  6. cmdb整体项目梳理(2)
  7. Android 短信开发学习
  8. 邀请合作如何表达_如何邀请大咖嘉宾来商群分享
  9. android 表格xml,【Android】利用表格布局,Android中xml文件与java的交互制作登录界面...
  10. 默认适应窗口_自适应网格分析带孔平板的应力集中问题
  11. 2021最新!某盘加速下载工具复活了,无需登录,打开即可高速下载(附下载)!
  12. 第01课:走进分布式中间件(课前必读)
  13. 如何处理春节效应——若干券商研究团队的经验
  14. 初探开源分布式WPA破解程序moscrack
  15. 记一道80%的人会答错的牛X面试题!
  16. 腾讯云4核8g10M轻量服务器支持多少人在线?
  17. arris sbr-ac1900p/sbr-ac3200p梅林固件
  18. 光纤收发器的选择与维护!
  19. 识别电路板上贴片电阻型号0805 0402 0603 1206封装信息
  20. 夏令营+预推免小结(中南 东南 浙大)

热门文章

  1. Jquery源码分析之匿名函数的自执行
  2. RAC修改数据库的spfile位置
  3. iOS常用CGRect的交错,边缘,中心的检测
  4. [CTO札记]防盗版新思路:招安
  5. 在KVM主机和虚拟机之间共享目录
  6. tomcat运行模式APR安装
  7. MySQL5.7登陆数据库管理控制平台问题 ERROR 1045(28000)
  8. linux网络管理三剑客
  9. c++设计一个不能被继承的类
  10. 浅析:seo工程师擅长的网站数据分析