二叉树的非递归遍历(先序、中序、后序和层序遍历)

[前文]

二叉树的非递归遍历有 先序遍历、中序遍历 后续遍历 和 层序遍历。

非递归算法实现的基本思路:使用堆栈。而层序遍历的实现:使用队列。

如下图所示的二叉树:

    

前序遍历顺序为:ABCDE  (先访问根节点,然后先序遍历其左子树,最后先序遍历其右子树)

中序遍历顺序为:CBDAE  (先中序遍历其左子树,然后访问很节点,最后中序遍历其右子树)

后续遍历顺序为:CDBEA  (先后序遍历其左子树,然后后续其右子树,最后访问根节点)

层序遍历顺序为:ABECD   (由上至下、从左到右遍历二叉树)

[准备]

  1. 堆栈的存储结构和相关操作(具体见: 堆栈的定义与操作——顺序存储和链式存储

  2. 队列的存储结构和相关操作(具体见:队列的定义与操作——顺序存储和链式存储

  3. 建立二叉树。

 1 typedef struct TreeNode *BinTree;
 2 struct TreeNode {
 3     char Data;
 4     BinTree Left;
 5     BinTree Right;
 6 };
 7
 8 BinTree CreateBinTree(BinTree T)
 9 {
10     char c;
11     scanf("%c", &c);
12     if ( c != ‘#‘ ) {
13         T = (BinTree)malloc(sizeof(struct TreeNode));
14         T->Data = c;
15         T->Left = CreateBinTree(T->Left);
16         T->Right = CreateBinTree(T->Right);
17     }
18     else {
19         T = NULL;
20     }
21     return T;
22 }

[实现]  

  1. 先序遍历

 1 void PreOrderTraverse(BinTree BT)
 2 {
 3     BinTree T = BT;
 4     Stack S = CreateStack();    /* 创建并初始化堆栈  */
 5     while ( T || !IsEmpty(S) ) {
 6         while ( T ) {         /* 一直向左并将沿途节点压入栈底  */
 7             printf("%c ", T->Data);    /* 打印节点数据 */
 8             Push(S, T);
 9             T = T->Left;
10         }
11         if ( !IsEmpty(S) ) {
12             T = Pop(S);            /* 节点弹出堆栈 */
13             T = T->Right;        /* 转向右子树 */
14         }
15     }
16 }

  2.中序遍历

 1 void InOrderTraverse(BinTree BT)
 2 {
 3     BinTree T = BT;
 4     Stack S = CreateStack();    /* 创建并初始化堆栈  */
 5     while ( T || !IsEmpty(S) ) {
 6         while ( T ) {         /* 一直向左并将沿途节点压入栈底  */
 7             Push(S, T);
 8             T = T->Left;
 9         }
10         if ( !IsEmpty(S) ) {
11             T = Pop(S);            /* 节点弹出堆栈 */
12             printf("%c ", T->Data);    /* 打印节点数据 */
13             T = T->Right;        /* 转向右子树 */
14         }
15     }
16 }

  3. 后序遍历

struct Node {
    BinTree BT;
    char Tag;
};
typedef struct Node *PtrToNode;

void PostOrderTraverse(BinTree T)
{
    BinTree P = T;
    struct Node *PNode;
    Stack S = CreateStack();

    while ( P || !IsEmpty(S) ) {
        // 遍历左子树
        while ( P ) {
            PNode = (struct Node*)malloc(sizeof(struct Node));
            PNode->BT = P;
            PNode->Tag = ‘L‘;    //  第一次被标记
            Push(S, PNode);
            P = P->Left;
        }
        // 栈不空 并且  栈顶元素 是第二次被标记
        while ( !IsEmpty(S) && GetTop(S)->Tag == ‘R‘ ) {
            PNode = Pop(S);
            printf("%c ", PNode->BT->Data);
        }

        if ( !IsEmpty(S) ) {
            PNode = GetTop(S);
            PNode->Tag = ‘R‘;    // 第二次被标记
            P = PNode->BT;
            P = P->Right;         // 转向右子树
        }
    }
}

  4. 层序遍历

 1 void LevelOrderTraverse(BinTree BT)
 2 {
 3     Queue Q;
 4     ElementType T;
 5
 6     if ( !BT )    return;    // 若是空树则返回
 7
 8     Q = CreateQueue();    // 创建空队列
 9     AddQ(Q, BT);
10     while ( !IsEmpty(Q) ) {
11         T = DeleteQ(Q);
12         printf("%c ", T->Data);
13         if ( T->Left )    AddQ(Q, T->Left);
14         if ( T->Right ) AddQ(Q, T->Right);
15     }
16 }

原文地址:https://www.cnblogs.com/wgxi/p/9974961.html

时间: 2024-10-22 14:16:18

二叉树的非递归遍历(先序、中序、后序和层序遍历)的相关文章

通过二叉树的中序和后序遍历序列构造二叉树(非递归)

题目:通过二叉树的中序和后序遍历序列构造二叉树 同样,使用分治法来实现是完全可以的,可是在LeetCode中运行这种方法的代码,总是会报错: Memory Limit Exceeded ,所以这里还是用栈来实现二叉树的构建. 与用先序和后序遍历构造二叉树的方法类似,但还是要做一些改变: 如果从后往前处理中序和后序的序列,则处理就为如下所示的情况: Reverse_Post: 根-右子树-左子树 Reverse_In: 右子树-根-左子树 这样处理方式和先序-中序就差不多了,只是将添加左孩子的情况

二叉树的非递归遍历--京东2015笔试回忆

题目回忆: C/C++研发试卷:偏重于数据结构的考察,编程题有2题+1题附加题: 1.输入整数n,求m,m>9,m中各个数位的乘积=n的最小整数;如n=36,m=49; 2.二叉树前序遍历的非递归实现(本文的总结) 3.求第n个数,这个序列满足(2^i)*(3^j)*(5^k),前7个为:2,3,4,5,6,8,10 .... 小题有基本的数据结构.程序运行结果.SQL题目. 4.删除表格用DROP命令,死锁产生的条件: 4.1互斥使用(资源独占) 一个资源每次只能给一个进程使用 4.2.不可强

二叉树的非递归遍历及算法分析

二叉树介绍 二叉树是一类重要的数据结构.二叉树常被用于实现二叉查找树和二叉堆.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree). 一种二叉树结点定义: struct bit_node { chardata; structbit_node *lchild,*rchild; }; 遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次.由于二叉树是

二叉树的非递归遍历(转)

原文地址 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点. 一.前序遍历 前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问. 1.递归实现 void pr

二叉树的非递归遍历C语言实现

腾讯面试中被问到二叉树的非递归遍历实现,当时记得不太清楚,回来专门复习了非递归的实现,整理代码如下: //采用二叉链表存储方式的二叉树,非递归中序遍历C语言实现代码 #include<stdio.h> #include <malloc.h> //函数结果状态代码 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //Status是

(转)二叉树的非递归遍历

转自: 二叉树的非递归遍历 http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html 二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都

二叉树的非递归遍历(转载)

二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点. 一.前序遍历 前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问. 1.递归实现 void preOrde

[算法]二叉树的非递归遍历算法

1.二叉树的非递归中序遍历算法 二叉树的中序遍历方法是:左中右,因此一开始会顺着根节点的左孩子一直往下(这点和先序遍历一样,这也是二者前面部分代码很相似的原因),到最后一个左孩子时尝试把它的右孩子塞进栈内,然后顺着它的的左孩子而下,直到不能访问为止.利用的栈FILO的特性,对每个节点都进行顺左孩子而下即可. 上代码: 1 void inOrder(TreeNode* root,vector<int>& inOrder) 2 { 3 stack<TreeNode*>st; 4

二叉树的非递归遍历,还有一点黑科技

二叉树的前中后序遍历,可以用递归秒解,看起来不值一提.但如果不允许采用递归,要怎么实现呢? 还是先来看看递归算法的实现吧: def visit( root): if root is not null: #1 visit(root.left) #2 visit(root.right) #3 上面展示的代码中有三个位置(#1,#2,#3)可以用来插入访问当前节点的代码,分别对应了前中后三种遍历.这三种不同的设定,实际上表达的是访问节点的不同时机. 我们可以用进栈和出栈来模拟这些递归的过程,在跟#1,