#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. 超越BERT的模型有哪些?
  2. nginx upstream 调度策略
  3. Nodejs Hello world benchmark
  4. mysql blob 存储乱码_mysql 保存 blob 类型数据 乱码 解决
  5. mybatis-config.xml整理
  6. Gentoo 安装日记 17(修改/etc/fstab)
  7. ActFrameWork集成Beetlsql的Mapper功能
  8. python重命名异常_python异常处理
  9. C/C++位域结构深入解析
  10. shell -nginx启动脚本
  11. java instant获取微秒转成日期格式_Java8新特性时间日期库DateTime API及示例
  12. VALSE学习(八):矿视-轻量级深度模型的研究与实践
  13. Qt QLabel实现自动换行 字符断行 自适应
  14. 连上WiFi后,笔记本离路由器比较近时,电脑播音偶尔卡音
  15. Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解
  16. 虚拟机下ROS调用笔记本摄像头
  17. 微信小程序,高德地图
  18. 计算机学业水平测试初中生操作题,初中学业水平考试信息技术考试操作题常见题型及作答方法...
  19. 安卓 Charles证书的安装
  20. Java基于Redis实现“附近的人”(含源码下载)

热门文章

  1. 使用JAVA建立稳定的多线程服务器
  2. 中断的顶半部和底半部
  3. 零基础到精通Linux,从这篇文章开始
  4. Lync Server 2010标准版系列PART1:基础构建
  5. 【笔记】mysql入门语句8条
  6. nginx rewrite中last和break的区别
  7. RxSwift 小记 Error Handling Operators(catchError,retry)
  8. JavaScript中 DOM操作方法
  9. 如何利用框选工具获取多边形范围?
  10. Java性能优化:正确的解析JSON文件