我是靠谱客的博主 安详芒果,最近开发中收集的这篇文章主要介绍三种遍历树的算法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

递归与非递归转换的基础知识是能够正确理解三种树的遍历方法:前序,中序和后序,第一篇就是关于这三种遍历方法的递归和非递归算法。

如何用栈实现递归与非递归的转换(一)三种遍历树的算法

一.为什么要学习递归与非递归的转换的实现方法? 
1)并不是每一门语言都支持递归的. 
2)有助于理解递归的本质. 
3)有助于理解栈,树等数据结构.

二.三种遍历树的递归和非递归算法 
    递归与非递归的转换基于以下的原理:所有的递归程序都可以用树结构表示出来.需要说明的是,这个"原理"并没有经过严格的数学证明,只是我的一个猜想,不过在至少在我遇到的例子中是适用的.学习过树结构的人都知道,有三种方法可以遍历树:前序,中序,后序.理解这三种遍历方式的递归和非递归的表达方式是能够正确实现转换的关键之处,所以我们先来谈谈这个.需要说明的是,这里以特殊的二叉树来说明,不过大多数情况下二叉树已经够用,而且理解了二叉树的遍历,其它的树遍历方式就不难。 
            了. 
            1)前序遍历

            a)递归方式: 
                  void preorder_recursive(Bitree T)      /* 先序遍历二叉树的递归算法 */ 
                        { 
                           if (T) { 
                              visit(T);          /* 访问当前结点 */ 
                              preorder_recursive(T->lchild);   /* 访问左子树 */ 
                              preorder_recursive(T->rchild);   /* 访问右子树 */ 
                           } 
                        }


            b)非递归方式 
                  void preorder_nonrecursive(Bitree T)      /* 先序遍历二叉树的非递归算法 */ 
                        { 
                           initstack(S); 
                           push(S,T);             /* 根指针进栈 */ 
                           while(!stackempty(S)) { 
                              while(gettop(S,p)&&p) {      /* 向左走到尽头 */ 
                                 visit(p);      /* 每向前走一步都访问当前结点 */ 
                                 push(S,p->lchild); 
                              } 
                              pop(S,p); 
                              if(!stackempty(S)) {      /* 向右走一步 */ 
                                 pop(S,p); 
                                 push(S,p->rchild); 
                              } 
                           } 
                        }

            2)中序遍历

            a)递归方式 
                  void inorder_recursive(Bitree T)      /* 中序遍历二叉树的递归算法 */ 
                        { 
                           if (T) { 
                              inorder_recursive(T->lchild);   /* 访问左子树 */ 
                              visit(T);          /* 访问当前结点 */ 
                              inorder_recursive(T->rchild);   /* 访问右子树 */ 
                           } 
                        }


            b)非递归方式 
                  void inorder_nonrecursive(Bitree T) 
                        { 
                           initstack(S);            /* 初始化栈 */ 
                           push(S, T);            /* 根指针入栈 */

                           while (!stackempty(S)) {          
                              while (gettop(S, p) && p)    /* 向左走到尽头 */ 
                                 push(S, p->lchild); 
                              pop(S, p);         /* 空指针退栈 */ 
                              if (!stackempty(S)) { 
                                 pop(S, p); 
                                 visit(p);      /* 访问当前结点 */ 
                                 push(S, p->rchild);   /* 向右走一步 */ 
                              } 
                           } 
                        }


            3)后序遍历

            a)递归方式 
                  void postorder_recursive(Bitree T)      /* 中序遍历二叉树的递归算法 */ 
                        { 
                           if (T) { 
                              postorder_recursive(T->lchild);   /* 访问左子树 */ 
                              postorder_recursive(T->rchild);   /* 访问右子树 */ 
                              visit(T);             /* 访问当前结点 */ 
                           } 
                        }


            b)非递归方式 
                  typedef struct { 
                           BTNode* ptr; 
                           enum {0,1,2} mark; 
                        } PMType;                /* 有mark域的结点指针类型 */

                        void postorder_nonrecursive(BiTree T)      /* 
                  后续遍历二叉树的非递归算法 */ 
                        { 
                           PMType a; 
                           initstack(S);             /* S的元素为PMType类型 */ 
                           push (S,{T,0});          /* 根结点入栈 */ 
                           while(!stackempty(S)) { 
                              pop(S,a); 
                              switch(a.mark) 
                              { 
                              case 0: 
                                 push(S,{a.ptr,1});    /* 修改mark域 */ 
                                 if(a.ptr->lchild) 
                                    push(S,{a.ptr->lchild,0}); /* 访问左子树 */ 
                                 break; 
                              case 1: 
                                 push(S,{a.ptr,2});    /* 修改mark域 */ 
                                 if(a.ptr->rchild) 
                                    push(S,{a.ptr->rchild,0}); /* 访问右子树 */ 
                                 break; 
                              case 2: 
                                 visit(a.ptr);       /* 访问结点 */ 
                              } 
                           } 
                        }

最后

以上就是安详芒果为你收集整理的三种遍历树的算法的全部内容,希望文章能够帮你解决三种遍历树的算法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部