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

转载 2018年04月16日 14:04:53

原文链接:点击打开链接

摘要: 这篇帖子的代码是在上大学修数据结构的时候写的,写完就上传到CSDN提供下载了,那会比较贪心,设置的下载积分比较高。工作后慢慢习惯分享,偶然看到当时上传的简单几行代码还要积分。干脆直接把代码拿过来写成帖子也省去了路过同仁下载的麻烦。

为什么写这篇帖子

这篇帖子的代码是在上大学修数据结构的时候写的,写完就上传提供下载了,那会比较贪心,设置的下载积分比较高。工作后慢慢习惯分享,偶然看到当时上传的简单几行代码还要积分。干脆直接把代码拿过来写成帖子也省去了路过同仁下载的麻烦。

这篇帖子都写了什么

如题,这篇帖子给出了二叉树三种遍历算法的递归和非递归实现。目前,我只给出了算法的具体代码实现,具体的算法描述并没有提及(貌似也没有必要说,算法很简单)。如果有需要我后面可以把算法描述流程图补充上。

顺便提一下本文中的算法使用C描述。

具体聊聊代码

开始前的准备工作

开始前还有准备工作吗?当然有,我们需要自定义栈的数据结构和操作算法算法以及二叉树的数据结构和建树算法。

栈数据结构及操作实现

//定义堆栈结构
typedef struct SNode {
    BiTree Data;
    struct SNode *next;
}SNode, *LStack;

//建栈
void InitStack(LStack &s)
{
    s = (LStack)malloc(sizeof(LStack));
    s->next = NULL;
}
//压栈
void Push(LStack &S, BiTree c)
{
    LStack p;
    p = (LStack)malloc(sizeof(LStack));
    p->Data = c;
    p->next = S->next;
    S->next = p;
}
//出栈
void Pop(LStack &S, BiTree &c)
{
    LStack p;
    p = (LStack)malloc(sizeof(LStack));
    if (S->next != NULL)
    {
        p = S->next;
        S->next = p->next;
        c = p->Data;
    }
}

二叉树数据结构及建树实现

//定义二叉树结构
typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

//递归按中序遍历建树,输入#号代表数空
void CreateBiTree(BiTree &T)
{
    char ch;
    fflush(stdin);//清除缓冲区
    scanf("%c", &ch);
    if (ch == '#')
    {
        T = NULL;
    }
    else
    {
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

遍历算法实现

递归先序遍历二叉树

//递归先序遍历二叉树
void PreOrderTraverse(BiTree T)
{
    if (T)
    {
        printf("%c ", T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}

递归中序遍历二叉树

//递归中序遍历二叉树
void InOrderTraverse(BiTree T)
{
    if (T)
    {
        InOrderTraverse(T->lchild);
        printf("%c ", T->data);
        InOrderTraverse(T->rchild);
    }
}

递归后序遍历二叉树

//递归后序遍历二叉树
void HOrderTraverse(BiTree T)
{
    if (T)
    {
        HOrderTraverse(T->lchild);
        HOrderTraverse(T->rchild);
        printf("%c ", T->data);
    }
}

非递归先序遍历

//非递归先序遍历
void POrder(BiTree T)
{
    LStack s;
    InitStack(s);
    while ((T != NULL) || (s->next != NULL))
    {
        if (T != NULL)
        {
            printf("%c ", T->data);
            Push(s, T);
            T = T->lchild;
        }
        else
        {
            Pop(s, T);//回溯至父亲节点
            T = T->rchild;
        }
    }
}

非递归中序遍历

//非递归中序遍历
void IOrder(BiTree T)
{
    LStack s;
    InitStack(s);
    while ((T != NULL) || (s->next != NULL))
    {
        while (T != NULL)   // 左子树入栈
        {
            Push(s, T);
            T = T->lchild;
        }
        if (s->next != NULL)
        {
            Pop(s, T);
            printf("%c ", T->data);   // 访问根结点
            T = T->rchild;  // 通过下一次循环实现右子树遍历
        }
    }

}

非递归后序遍历

//非递归后序遍历
void HOrder(BiTree T)
{
    BiTree p = T, q = NULL;//q作用,记录p上次访问的节点
    LStack s;
    InitStack(s);
    Push(s, T);//根节点压栈
    while (s->next != NULL)//栈不空循环进行
    {
        if (p&&p != q)
        {
            Push(s, p);
            p = p->lchild;//找最左节点
        }
        else
        {
            Pop(s, p);
            if (s->next != NULL)//判断栈非空,如果栈空代表根节点已经出栈
            {
                if (p->rchild&&p->rchild != q)
                {
                    Push(s, p);//将节点重新压回栈
                    p = p->rchild;//进入右子树
                }
                else
                {
                    printf("%c ", p->data);
                    q = p;//防止节点多次重复进栈,陷入死循环
                }
            }
        }
    }
}

调用算法

int main()
{
    BiTree T;
    printf("按先序遍历递归建立二叉树:\n");
    CreateBiTree(T);
    printf("递归先序遍历二叉树:\n");
    PreOrderTraverse(T);
    printf("\n递归中序遍历二叉树:\n");
    InOrderTraverse(T);
    printf("\n递归后序遍历二叉树:\n");
    HOrderTraverse(T);
    printf("\n非递归先序遍历二叉树:\n");
    POrder(T);
    printf("\n非递归中序遍历二叉树:\n");
    IOrder(T);
    printf("\n非递归中序遍历二叉树:\n");
    HOrder(T);
    printf("\n");

    return 0;
}

调用结果如图
3

结束语

以上就是二叉树三种遍历算法的递归与非递归实现的具体代码,如有不明白的地方欢迎留言交流,若帖子中有错误的地方同样欢迎留言批评指正,在此谢过路过的各位大神。

.
.
.
.
.
.
你以为这就完了?最后再声情并茂的讲一讲什么是递归。
mmexport1523797170204


【数据结构与算法】二叉树递归与非递归遍历(附完整源码)

二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的。二叉树有前、中、后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但...
  • mmc_maodun
  • mmc_maodun
  • 2013-10-24 08:58:03
  • 41792

二叉树的非递归遍历及层次遍历

二叉树的基本操作请看:http://blog.csdn.net/sysu_arui/article/details/7865876 前面简答介绍了二叉树的基本操作,包括二叉树的建立,销毁,递归遍历,...
  • sysu_arui
  • sysu_arui
  • 2012-08-14 17:10:50
  • 14164

遍历二叉树-递归和非递归算法

遍历二叉树的三种方法:前序:根节点->左子树->右子树中序:左子树->根节点->右子树后序:左子树->右子树->根节点 非递归算法中序遍历二叉树,设S为一个栈,p为指向根节点的指针,处理过程如下:1)...
  • hbuxiaoshe
  • hbuxiaoshe
  • 2010-10-24 19:40:00
  • 10570

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

本文实现了对二叉树的递归遍历和非递归遍历,当然还包括了一些栈操作。           二叉树的遍历本质上其实就是入栈出栈的问题,递归算法简单且容易理解,但是效率始终是个问题。非递归算法可以清楚的知道...
  • B_boyi
  • B_boyi
  • 2016-05-14 10:35:17
  • 580

二叉树的四种遍历(递归、非递归)

1、递归遍历/** * 先序遍历 * @param root */ public void printFirstTree(TreeNode root){ ...
  • GYQJN
  • GYQJN
  • 2016-09-30 11:20:33
  • 1886

二叉树遍历的递归、非递归算法(Java实现)

二叉树先序遍历、中序遍历、后序遍历的递归以及非递归算法(Java实现)
  • apandi_
  • apandi_
  • 2016-10-24 22:35:48
  • 2584

二叉树的前序、中序、后序的递归与非递归遍历算法实现

看代码一目了然。 C++代码:#include #include #include using namespace std;//二叉树节点 typedef struct BitNode{ ...
  • u011954296
  • u011954296
  • 2016-07-12 12:31:34
  • 3116

二叉树的非递归遍历的解析与实现----java实现

先序遍历 根据先序遍历的访问的顺序,先访问根节点,然后再访问左子树和右子树。对于树中的任意一个节点,都可以看做是一个根节点(也可以看成是一个树),因此可以直接访问根节点,访问完根节点,如果它的左子树...
  • snow_7
  • snow_7
  • 2016-06-30 10:23:37
  • 1155

二叉树的递归和非递归方式的三种遍历

二叉树的三种遍历方式,前序遍历,中序遍历,后序遍历,中的前中后都是指的是根节点的访问顺序,这三种遍历方式的概念在这里就不多说了,太普遍了! 二叉树的建立 我们这里以前序遍历为例: 我们先定...
  • woshinannan741
  • woshinannan741
  • 2016-10-16 13:18:57
  • 2538

对于二叉树三种非递归遍历方式的理解

利用栈实现二叉树的先序,中序,后序遍历的非递归操作 栈是一种先进后出的数据结构,其本质应是记录作用,支撑回溯(即按原路线返回);因此,基于其的二叉树遍历操作深刻的体现了其特性: 1.先入、后出,只...
  • sdulibh
  • sdulibh
  • 2016-01-24 11:25:30
  • 3711
收藏助手
不良信息举报
您举报文章:二叉树的递归非递归遍历算法
举报原因:
原因补充:

(最多只允许输入30个字)