二叉树的建造、递归与非递归遍历
#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; }
输出效果如图所示
二叉树的建造、递归与非递归遍历相关推荐
- 二叉树路径应用举例(基于非递归后序遍历)
#include "stdafx.h" #include <iostream> #include <fstream>using namespace std; ...
- 遍历二叉树的各种操作(非递归遍历)
先使用先序的方法建立一棵二叉树,然后分别使用递归与非递归的方法实现前序.中序.后序遍历二叉树,并使用了两种方法来进行层次遍历二叉树,一种方法就是使用STL中的queue,另外一种方法就是定义了一个数组 ...
- 二叉树的几种递归和非递归式遍历:
二叉树的几种递归和非递归式遍历: 1 #include <fstream> 2 #include <iostream> 3 4 using namespace std; 5 6 ...
- 分别用递归和非递归方式实现二叉树先序、中序和后序遍历(java实现)
分别用递归和非递归方式实现二叉树先序.中序和后序遍历 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点.我们约定:先序遍历顺序 为根.左.右;中序遍历顺序为左.根.右;后序遍历顺序为左 ...
- 转载:二叉树的前中后和层序遍历详细图解(递归和非递归写法)
二叉树的前中后和层序遍历详细图解(递归和非递归写法) Monster_ii 2018-08-27 17:01:53 50530 收藏 403 分类专栏: 数据结构拾遗 文章标签: 二叉树 前序 中序 ...
- 九十五、二叉树的递归和非递归的遍历算法模板
@Author:Runsen 刷Leetcode,需要知道一定的算法模板,本次先总结下二叉树的递归和非递归的遍历算法模板. 二叉树的四种遍历方式,前中后加上层序遍历.对于二叉树的前中后层序遍历,每种遍 ...
- 二叉树层序遍历递归与非递归_二叉树基础(1)-构建和遍历(递归和非递归)...
二叉树的构建有2种方式:1.直接输入数字.2.根据两种顺序来判断另外一中顺序(后面会提到) 这里分享第一种构建方式,二叉树的前中后三种遍历方式(递归和非递归版本),和二叉树的层次遍历. 见代码demo ...
- 二叉树的遍历:先序 中序 后序遍历的递归与非递归实现及层序遍历
二叉树的定义:一种基本的数据结构,是一种每个节点的儿子数目都不多于2的树 树节点的定义如下: // 树(节点)定义 struct TreeNode {int data; // 值TreeNode* l ...
- 左神算法:分别用递归和非递归方式实现二叉树先序、中序和后序遍历(Java版)
本题来自左神<程序员代码面试指南>"分别用递归和非递归方式实现二叉树先序.中序和后序遍历"题目. 题目 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点 ...
- 二叉树创建及遍历算法(递归及非递归)(转)
//二叉树处理头文件 //包括二叉树的结构定义,二叉树的创建,遍历算法(递归及非递归), /* 作者:成晓旭 时间:2001年10月7日(18:49:38-20:00:00) 内容:完成二叉树创建,二 ...
最新文章
- 超越BERT的模型有哪些?
- nginx upstream 调度策略
- Nodejs Hello world benchmark
- mysql blob 存储乱码_mysql 保存 blob 类型数据 乱码 解决
- mybatis-config.xml整理
- Gentoo 安装日记 17(修改/etc/fstab)
- ActFrameWork集成Beetlsql的Mapper功能
- python重命名异常_python异常处理
- C/C++位域结构深入解析
- shell -nginx启动脚本
- java instant获取微秒转成日期格式_Java8新特性时间日期库DateTime API及示例
- VALSE学习(八):矿视-轻量级深度模型的研究与实践
- Qt QLabel实现自动换行 字符断行 自适应
- 连上WiFi后,笔记本离路由器比较近时,电脑播音偶尔卡音
- Spring Boot 2.x基础教程:进程内缓存的使用与Cache注解详解
- 虚拟机下ROS调用笔记本摄像头
- 微信小程序,高德地图
- 计算机学业水平测试初中生操作题,初中学业水平考试信息技术考试操作题常见题型及作答方法...
- 安卓 Charles证书的安装
- Java基于Redis实现“附近的人”(含源码下载)