非递归实现二叉树的遍历(前序、中序、后序)

树的定义本是递归定义,所以采用递归的方法实现遍历算法,更加让人理解,且代码简单方便。若采用非递归的方法实现,须得利用栈模拟实现。

栈的特点(后进先出)

非递归实现二叉树的前序遍历:

原理如图所示:

参考代码如下:

void _PrevOrder(Node* root)//非递归实现前序遍历

{

stack<Node*> s;

if(root == NULL)

return;

s.push(root);

while (!s.empty())

{

root = s.top();

cout<<root->_data<<" ";

s.pop();

if (root->_right)

{

s.push(root->_right);

}

if(root->_left)

{

s.push(root->_left);

}

}

}

非递归实现二叉树的中序遍历

原理:

先从二叉树的最左边进行遍历(1、2、3),且一边遍历,一边入栈,当当到达结点3时,因为3的左右子树都为空,此时需弹出结点3,栈顶元素变为2,再遍历2的右子树的左结点,因为4的左右子树都为空,此时需弹出2,压人4,左子树已遍历结束,弹出4,再弹出1,依照遍历左子树,遍历右子树。

参考代码如下:

void _InOrder(Node* root)//非递归实现中序遍历

{

stack<Node*> s;

Node* cur = root;

while (cur || !s.empty())

{

while (cur)

{

s.push(cur);

cur = cur->_left;

}

Node* top = s.top();

cout<<top->_data<<" ";

s.pop();

cur = top->_right;

}

}

非递归实现二叉树的后序遍历

步骤:

1、借助栈实现后序遍历,先找到最左边且为最下边的结点3(一边找,一边入栈)

2、若3没有右子树,则弹出3且打印结点3,还需要引入一个指向当前弹出结点的指针prev

3、若3有右子树,则需要遍历右子树,遍历结束才可以打印并弹出结点3,重复此三步骤可完成后序遍历。

参考代码如下:

void _PosOrder(Node* root)//非递归实现后序遍历

{

Node* cur = root;

Node* prev = NULL;

stack<Node*> s;

if(root == NULL)

return;

while (cur || !s.empty())

{

while (cur)

{

s.push(cur);

cur = cur->_left;

}

cur = s.top();

if(cur->_right == NULL || cur->_right == prev)

{

cout<<cur->_data<<" ";

s.pop();

prev = cur;

cur = NULL;

}

else

{

cur = cur->_right;

}

}

}

时间: 2024-12-08 17:28:42

非递归实现二叉树的遍历(前序、中序、后序)的相关文章

非递归实现二叉树的遍历

二叉树遍历是树的最基本算法之一,是二叉树上进行其它运算之基础. 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问. 访问结点所做的操作依赖于具体的应用问题. ① 前序遍历(PreorderTraversal亦称(先序遍历)) --访问根结点的操作发生在遍历其左右子树之前. ② 中序遍历(InorderTraversal) --访问根结点的操作发生在遍历其左右子树之中(间). ③ 后序遍历(PostorderTraversal) --访问根结点的操作发生

Java数据结构四之——二叉树的前、中、后序遍历

程序来自Program Creek 前 Preorder binary tree traversal is a classic interview problem about trees. The key to solve this problem is to understand the following: What is preorder? (parent node is processed before its children) Use Stack from Java Core lib

二叉树的先序/中序/后序/层次遍历

[简介] 树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用. 二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作"左子树"(left subtree)和"右子树"(right subtree).二叉树常被用作二叉查找树和二叉堆或是二叉排序树.二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有2的 i -1次方个结点:深度为k的二叉树至多有2^(k) -1个结点:对任何一棵二叉树T,

二叉树的前序/中序/后序遍历方法的递归与循环的实现

对于二叉树的三种遍历方法, 递归方法实现起来简单,明白.但是效率不好,并且不安全,可能会栈溢出.循环的实现,肯定是基于栈的数据结构来实现,要复杂一些.代码如下: 前序遍历的实现: // 前序遍历 ----基于递归 void PreorderTraversal(BinaryTreeNode* pRoot_) { // 为空时,直接返回了 if (!pRoot_) return; std::cout << pRoot_->m_nValue << " "; Pr

C语言非递归实现二叉树的先序、中序、后序、层序遍历

C语言非递归实现二叉树的先序.中序.后序.层序遍历代码如下: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stack> 4 #include <queue> 5 using namespace std; 6 7 //*****二叉树的二叉链表存储表示*****// 8 typedef struct BiNode 9 { 10 char data; 11 struct BiNode *lchil

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

前序中序后序遍历非递归实现

#include<iostream> #include<vector> #include<stack> #include<string> #include<algorithm> #include<numeric> using namespace std; class node{ public: int val; node* left; node* right; node():val(0),left(NULL),right(NULL){

二叉树的前序中序后序遍历相互求法

二叉树的前中后序遍历,他们的递归非递归.还有广度遍历,参见二叉树的前中后序遍历迭代&广度遍历和二叉树的前中后序遍历简单的递归 现在记录已知二叉树的前序中序后序遍历的两个,求另外一个.一般,这两个中一定有中序遍历. 1.已知前序和中序,求后序遍历: 前序:ABDECFG  中序:DBEAFCG 思路简单:前序的第一个节点就是根节点, 中序中找到根节点的位置,根节点之前是其左子树,之后是右子树   按此顺序,依次在左子树部分遍历,右子树部分遍历 C++ 代码: TreeNode *BinaryTre

二叉树的存储方式以及递归和非递归的三种遍历方式

树的定义和基本术语 树(Tree)是n(n>=0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件: (1)有且仅有一个特定的称为根(Root)的结点: (2)其余的结点可分为m(m>=0)个互不相交的子集T1,T2,T3-Tm,其中每个子集又是一棵树,并称其为子树(Subtree). 树形结构应用实例: 1.日常生活:家族谱.行政组织结构:书的目录 2.计算机:资源管理器的文件夹: 编译程序:用树表示源程序的语法结构: 数据库系统:用树组织信息: 分析算法:用树来描述其执行过程: