二叉树的建造、递归与非递归遍历
来源:互联网 发布:php sqlsrv 编辑:程序博客网 时间:2024/06/05 13:32
#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表示该节点的子树为NULLvoid 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;}
输出效果如图所示
0 0
- 二叉树的建造、递归与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树的递归遍历与非递归遍历
- 二叉树 递归 与 非递归 遍历
- 递归与非递归二叉树遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 二叉树递归与非递归遍历
- 遍历二叉树(递归与非递归)
- 二叉树遍历的递归与非递归版本
- phpstudy apache无法启动解决方法,phpstudy教程,动态IP无公网IP时phpstudy网站发布到外网
- HDU 2639 Bone Collector II(01背包变型)
- Collection , List , Set 和 Map 用法和区别
- xUtils
- 程序员应戒除一些坏习惯
- 二叉树的建造、递归与非递归遍历
- ehcache监听工厂
- android中Timer和TimerTask的应用
- 非阻塞模式
- GetDocument()
- GYP工具Generate Your Projects
- WEBX2.0学习源码分析(一)初识webx2.0 基本目录结构
- Oracle PL/SQL基础
- 关于判断长字符串中是否完全包含短字符串的程序