史上最简明易懂非递归遍历二叉树算法

史上最简明易懂非递归遍历二叉树算法
巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo)

遍历二叉树的递归函数是体现了算法之美的高妙算法,思路清晰,代码简洁,读之赏心悦目。代码例如以下:
程序代码:

void PreOrderTraverse_R(BiTree BT) // 採用递归方式先序遍历二叉树BT
{
     if(BT != NULL)
    {
        printf( " %c ", BT->data); // 输出该结点(根结点) 
        PreOrderTraverse_R(BT->lchild);   // 遍历左子树 
        PreOrderTraverse_R(BT->rchild); // 遍历右子树
    }
}

void InOrderTraverse_R(BiTree BT) // 採用递归方式中序遍历二叉树BT
{
     if(BT != NULL)
    {
        InOrderTraverse_R(BT->lchild);   // 遍历左子树 
        printf( " %c ", BT->data); // 输出该结点(根结点) 
        InOrderTraverse_R(BT->rchild); // 遍历右子树
    }
}

void PostOrderTraverse_R(BiTree BT) // 採用递归方式后序遍历二叉树BT
{
     if(BT != NULL)
    {
        PostOrderTraverse_R(BT->lchild);   // 遍历左子树 
        PostOrderTraverse_R(BT->rchild); // 遍历右子树
        printf( " %c ", BT->data); // 输出该结点(根结点) 
    }
}

相较之下,大部分流传的非递归遍历二叉树算法语言晦涩,面目可憎,尽管利用了栈数据结构来模拟递归遍历过程,但思路和表达形式上未能与递归算法相应起来,造成刚開始学习的人理解上的困惑。假设可以将非递归算法和递归算法相互相应,则可大慷慨便刚開始学习的人理解二者间的等效性。
我们知道,编译器在调用函数时会分配一个栈空间,以存储必要信息,假设该函数调用了别的函数,其栈空间会一直保留,直到该函数最后一条语句运行完成,才会释放其栈空间。在模拟非递归算法的时候,我们须要手工分配和释放栈空间。
三种不同的遍历方式差别在于栈空间的释放时机和输出结点信息时机的不同:先序和中序遍历是在訪问栈顶元素的右孩子(右子树)之前退栈,而后序遍历在訪问右子树之后退栈;先序遍历是在某结点入栈时输出其信息,而中序和后序遍历是在该结点退栈时输出其信息。
    不管是递归算法还是非递归算法,都遵循上述规则,二者能够一一相应。图演示样例如以下:


附录:非递归算法代码例如以下:

void PreOrderTraverse_S(BiTree BT)//採用非递归方式先序遍历二叉树BT

{

       BiTreep, stack[MAXSIZE];//p表示当前结点,栈stack[]用来存储结点

       inttop = -1; //栈空

      

       if(BT != NULL)//先推断是否为空树

       {

       p = BT;

       while (p || top >= 0)

       {

           if (p != NULL) //先输出结点数据,再遍历左孩子

           {

                  printf("%c",p->data);//输出该结点

                   stack[++top] = p;

                  p = p->lchild;

           }

           else

           {

                   p = stack[top--]->rchild; //訪问栈顶元素右孩子,并退栈

           }

       }

    }

}

 

void InOrderTraverse_S(BiTree BT)//採用非递归方式中序遍历二叉树BT

{

       BiTreep, stack[MAXSIZE];//p表示当前结点,栈stack[]用来存储结点

       inttop = -1; //栈空

      

       if(BT != NULL)//先推断是否为空树

       {

       p = BT;

       while (p || top >= 0)

       {

           if (p != NULL)//首先訪问左子树

           {

                   stack[++top] = p;

                   p = p->lchild;

           }

           else

           {

                   printf("%c",stack[top]->data);//输出栈顶元素

                   p = stack[top--]->rchild; //訪问栈顶元素右孩子,并退栈

           }

       }

    }

}

 

void PostOrderTraverse_S(BiTree BT)//採用非递归方式后序遍历二叉树BT

{

       BiTreep, stack[MAXSIZE];//p表示当前结点,栈stack[]用来存储结点

       inttag[MAXSIZE] = {0}; //用来标志栈顶元素的右孩子是否被訪问过,0表示未訪问,1表示已訪问

       inttop = -1; //栈空

      

       if(BT != NULL)//先推断是否为空树

       {

       p = BT;

       while (p || top >= 0)

       {

           if (p != NULL) //首先訪问左子树

           {

                   stack[++top] = p;

                   tag[top] = 0;

                   p = p->lchild;

           }

           else if (tag[top] == 0) //若右子树尚未訪问,訪问栈顶元素右孩子,并做好标记

                     {

                    p= stack[top]->rchild;

                    tag[top]= 1;

                     }

                     else//否则输出栈顶元素并退栈

           {

                   printf("%c",stack[top--]->data);

           }

       }

    }

}






转载于:https://www.cnblogs.com/gcczhongduan/p/4279268.html

内容概要:本文详细介绍了施耐德M580系列PLC的存储结构、系统硬件架构、上电写入程序及CPU冗余特性。在存储结构方面,涵盖拓扑寻址、Device DDT远程寻址以及寄存器寻址三种方式,详细解释了不同类型的寻址方法及其应用场景。系统硬件架构部分,阐述了小系统的构建要素,包括CPU、机架和模块的选择与配置,并介绍了常见的系统拓扑结构,如简单的机架间拓扑和远程子站以太网菊花链等。上电写入程序环节,说明了通过USB和以太网两种接口进行程序下载的具体步骤,特别是针对初次下载时IP地址的设置方法。后,CPU冗余部分重点描述了热备功能的实现机制,包括IP通讯地址配置和热备拓扑结构。 适合人群:从事工业自动化领域工作的技术人员,特别是对PLC编程及系统集成有一定了解的工程师。 使用场景及目标:①帮助工程师理解施耐德M580系列PLC的寻址机制,以便更好地进行模块配置和编程;②指导工程师完成小系统的搭建,优化系统拓扑结构的设计;③提供详细的上电写入程序指南,确保程序下载顺利进行;④解释CPU冗余的实现方式,提高系统的稳定性和可靠性。 其他说明:文中还涉及一些特殊模块的功能介绍,如定时器事件和Modbus串口通讯模块,这些内容有助于用户深入了解M580系列PLC的高级应用。此外,附录部分提供了远程子站和热备冗余系统的实物图片,便于用户直观理解相关概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值