二叉树的前序/中序/后续遍历(递归+非递归)

  这几日又把二叉树的递归写了一遍,原来是用C写的,自己写了一个栈,这一次直接用的C++,使用了自带的栈结构。代码如下:

  1 /*************************************************************************
  2     > Author: Yves
  3     > E-mail: [email protected]
  4     > File Name: BiTreeNew.cpp
  5     > Description: ...
  6     > Created  Time: 2015-05-17. 15:51:24
  7     > Modified Time: 2015-05-17. 15:51:24
  8  ************************************************************************/
  9
 10 #include<stack>
 11 #include<cstdlib>
 12 #include<stdio.h>
 13 #include<iostream>
 14 using namespace std;
 15
 16 typedef char ElemType;
 17
 18 typedef struct tagBiTreeNode
 19 {
 20     ElemType data;
 21     struct tagBiTreeNode* leftChild;
 22     struct tagBiTreeNode* rightChild;
 23 }BiTreeNode, *pBiTreeNode;//指向BiTNode的指针
 24
 25 //创建二叉树
 26 static void CreatBiTree(pBiTreeNode *root);
 27 //访问树
 28 static void VisitTree(pBiTreeNode p, const int level);
 29 //前序递归遍历
 30 static void PreOrderRecursiveTraversal(const pBiTreeNode root, int level, void (*VisitTree)(pBiTreeNode p, const int level));
 31 //前序非递归遍历
 32 static void PreRecursiveTraversal(const pBiTreeNode root, void (*VisitTree)(pBiTreeNode p, const int level));
 33 //中序递归遍历
 34 static void InOrderRecursiveTraversal(const pBiTreeNode root, int level, void (*VisitTree)(pBiTreeNode p, const int level));
 35 //中序非递归遍历
 36 static void InOrdeTraversal(const pBiTreeNode root, void (*VisitTree)(pBiTreeNode p, const int level));
 37 //后序递归遍历
 38 static void PostOrderRecursiveTraversal(const pBiTreeNode root, int level, void (*VisitTree)(pBiTreeNode p, const int level));
 39 //后序非递归遍历
 40 static void PostOrderTraversal(const pBiTreeNode root, void (*VisitTree)(pBiTreeNode p, const int level));
 41
 42 static void CreatBiTree(pBiTreeNode *root)
 43 {
 44     /*Here we creat the tree in preorder, so the input
 45     sequences must comply with the preorder*/
 46     ElemType c;
 47     cin>>c;
 48     if(c != ‘#‘)
 49     {
 50     *root = (BiTreeNode*)malloc(sizeof(BiTreeNode));
 51         (*root)->data = c;
 52         CreatBiTree(&(*root)->leftChild);
 53         CreatBiTree(&(*root)->rightChild);
 54     }else
 55     {
 56         *root = NULL;
 57         return;
 58     }
 59 }
 60
 61 static void VisitTree(pBiTreeNode p, const int level)
 62 {
 63     if(level > 0)
 64     {
 65         cout<<p->data<<" is on the level "<<level<<"."<<endl;
 66     }
 67     else
 68     {
 69         cout<<p->data<<" ";
 70     }
 71 }
 72
 73 static void PreOrderRecursiveTraversal(const pBiTreeNode root, int level, void (*VisitTree)(pBiTreeNode p, const int level))
 74 {
 75     if(root == NULL)
 76     {
 77         return;
 78     }
 79     VisitTree(root, level);
 80     PreOrderRecursiveTraversal(root->leftChild, level + 1, VisitTree);
 81     PreOrderRecursiveTraversal(root->rightChild, level + 1, VisitTree);
 82 }
 83 static void PreRecursiveTraversal(const pBiTreeNode root, void (*VisitTree)(pBiTreeNode p, const int level))
 84 {
 85     if(root == NULL)
 86     {
 87         return;
 88     }
 89     stack<pBiTreeNode> s;
 90     pBiTreeNode p;
 91     p = root;
 92     while(!s.empty() || p != NULL)
 93     {
 94         while(p != NULL)
 95         {
 96             VisitTree(p, 0);
 97             s.push(p);
 98             p = p->leftChild;
 99         }
100         if(!s.empty())
101         {
102             p = s.top();
103             s.pop();
104             p = p->rightChild;
105         }
106     }
107 }
108 static void InOrderRecursiveTraversal(const pBiTreeNode root,int level, void (*VisitTree)(pBiTreeNode p, const int level))
109 {
110     if(root == NULL)
111     {
112         return;
113     }
114     InOrderRecursiveTraversal(root->leftChild, level + 1, VisitTree);
115     VisitTree(root, level);
116     InOrderRecursiveTraversal(root->rightChild, level + 1, VisitTree);
117 }
118 static void InOrderTraversal(const pBiTreeNode root, void (*VisitTree)(pBiTreeNode p, const int level))
119 {
120     if(root == NULL)
121     {
122         return;
123     }
124     stack<pBiTreeNode> s;
125     pBiTreeNode p;
126     p = root;
127     while(!s.empty() || p != NULL)
128     {
129         while(p != NULL)
130         {
131             s.push(p);
132             p = p->leftChild;
133         }
134         if(!s.empty())
135         {
136             p = s.top();
137             VisitTree(p, 0);
138             s.pop();
139             p = p->rightChild;
140         }
141     }
142 }
143 static void PostOrderRecursiveTraversal(const pBiTreeNode root,int level, void (*VisitTree)(pBiTreeNode p, const int level))
144 {
145     if(root == NULL)
146     {
147         return;
148     }
149     PostOrderRecursiveTraversal(root->leftChild, level + 1, VisitTree);
150     PostOrderRecursiveTraversal(root->rightChild, level + 1, VisitTree);
151     VisitTree(root, level);
152 }
153 static void PostOrderTraversal(const pBiTreeNode root, void (*VisitTree)(pBiTreeNode p, const int level))
154 {
155     stack<pBiTreeNode> s;
156     pBiTreeNode pCurrentNode;
157     pBiTreeNode pPrecedingNode = NULL;
158     s.push(root);
159     while(!s.empty())
160     {
161         pCurrentNode = s.top();
162         /*There is two cases:
163         * 1, the lefechild and the rightchild is all NULL, meaning it is a leaf node,so we can visit it directly.
164         * 2, the preceding node is not NULL,in addtion, it is the rightchild or the leftchild of the curretn node.
165         * Notice because of our order of pushing nodes into stack, it is sure that the two nodes(leftchild,rightchild)
166         * have accessed yet if one of conditions satisfies:
167         *          pPrecedingNode == pCurrentNode->leftChild  or
168         *          pPrecedingNode == pCurrentNode->rightChild))
169         * of course, pPrecedingNode != NULL must be satisfied.
170         */
171         if((pCurrentNode->leftChild == NULL && pCurrentNode->rightChild == NULL)
172             || (pPrecedingNode != NULL && (pPrecedingNode == pCurrentNode->leftChild
173                     || pPrecedingNode == pCurrentNode->rightChild)))
174         {
175             VisitTree(pCurrentNode, 0);
176             s.pop();
177             pPrecedingNode = pCurrentNode;
178         }else
179         {
180             if(pCurrentNode->rightChild != NULL)
181             {
182                 s.push(pCurrentNode->rightChild);
183             }
184             if(pCurrentNode->leftChild != NULL)
185             {
186                 s.push(pCurrentNode->leftChild);
187             }
188         }
189     }
190 }
191
192
193 int main(void)
194 {
195     pBiTreeNode root;
196
197     cout<<"Please input the node of the tree(preorder sequence):  "<<endl;
198     CreatBiTree(&root);
199     cout<<endl;
200
201
202     cout<<"Traverse the tree in preorder(non-recursive):  "<<endl;
203     PreRecursiveTraversal(root, &VisitTree);
204     cout<<endl;
205     cout<<"Traverse the tree in preorder:  "<<endl;
206     PreOrderRecursiveTraversal(root,1,&VisitTree);
207     cout<<endl;
208
209
210     cout<<"Traverse the tree in inorder(non-recursive):  "<<endl;
211     InOrderTraversal(root, &VisitTree);
212     cout<<endl;
213     cout<<"Traverse the tree in inorder:  "<<endl;
214     InOrderRecursiveTraversal(root, 1, &VisitTree);
215     cout<<endl;
216
217     cout<<"Traverse the tree in postorder(non-recursive):  "<<endl;
218     PostOrderTraversal(root, &VisitTree);
219     cout<<endl;
220     cout<<"Traverse the tree in posteorder:  "<<endl;
221     PostOrderRecursiveTraversal(root, 1, &VisitTree);
222     cout<<endl;
223
224     return 0;
225 }
时间: 2024-10-31 07:49:39

二叉树的前序/中序/后续遍历(递归+非递归)的相关文章

数据结构之二叉树(前序 中序 后续线索话非递归方式)

节点: enum LinkType {                  THREAD,                  LINK }; template<class T> struct ThredBinaryNode {                  ThredBinaryNode *_left;                  ThredBinaryNode *_right;                  LinkType _left_tag;                 

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

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

二叉树遍历,深度有限遍历,广度优先遍历,前序中序后续优先遍历,层次遍历

首先明白两个概念: 1. 深度遍历包括前中后序遍历三种: 2. 广度优先遍历就是层次遍历. PS: 前中后序遍历,如果使用递归遍历,都很简单易理解: 如果使用非递归方式,首先想到的就应该是使用栈结构来控制整个过程,因为递归也是利用栈来实现的: 前中后序遍历的非递归方式中,后序遍历的非递归方式相比较而言,略复杂. 直接上代码: #include "stdlib.h" #include <iostream> #include <stack> #include <

二叉树的前序,中序,后序遍历

https://www.cnblogs.com/Franck/p/3792926.html 二叉树是最常见最重要的数据结构之一,它的定义如下: 二叉树(binary tree)是有限多个节点的集合,这个结合或者是空集,或者由一个根节点和两颗互不相交的.分别称为左子树和右子树的二叉树组成. 二叉树最基本的操作是遍历:一般约定遍历时左节点优先于右节点,这样根据根节点的遍历顺序可分为三种遍历操作:前序-先遍历根节点,再处理左右节点:中序-先遍历左节点,然后处理根节点,最后处理右节点:后序-先遍历左右节

hihocoder(第十周)二叉树(前序中序推后续)递推实现

题目 : 后序遍历 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在参与过了美食节之后,小Hi和小Ho在别的地方又玩耍了一阵子,在这个过程中,小Ho得到了一个非常有意思的玩具——一棵由小球和木棍连接起来的二叉树! 小Ho对这棵二叉树爱不释手,于是给它的每一个节点都标记了一个标号——一个属于A..Z的大写字母,并且没有任意两个节点的标号是一样的.小Hi也瞅准了这个机会,重新巩固了一下小Ho关于二叉树遍历的基础知识~就这样,日子安稳的过了两天. 这天,小Ho正好在求解

leetcode | 二叉树的前序遍历、中序遍历、后续遍历的非递归实现

Binary Tree Preorder Traversal:https://leetcode.com/problems/binary-tree-preorder-traversal/ Binary Tree Inorder Traversal :https://leetcode.com/problems/binary-tree-inorder-traversal/ Binary Tree Postorder Traversal:https://leetcode.com/problems/bin

数据结构之二叉树 (构造 拷贝构造 以及前序中序后续三种遍历方法)

首先二叉树的节点定义如下: struct BinaryNode {                  BinaryNode *_left;                  BinaryNode *_right;                  T _data;                 BinaryNode( T data ) :_data(data), _left( NULL), _right(NULL )                 {}; }; 二叉树的结构以及接口如下 te

非递归遍历二叉树的前序中序后序

/** * 二叉树先序遍历,非递归算法 * 1.申请一个新的栈,记为stack.然后将头节点head压入stack中. * 2.从stack弹出栈顶节点,记为cur,然后打印cur节点的值,再将cur右孩子(不为空) * 压入stack中,最后将cur的左孩子(不为空)压入stack中 * 3.不断重复步骤2,直到stack为空,全部过程结束. * @param head */ public void preOrderNoRecur(Node head){ System.out.print("非

二叉树的前序中序后序遍历-非递归-使用同一段代码实现

树的遍历通常使用递归,因为它的实现更简单,代码也更容易理解. 但在面试,或者特殊的情境中会使用到迭代算法(非递归). 此时需要使用栈去模拟函数栈调用过程. 本文将给出一段代码去实现这三种遍历 相比于传统的方式:前序遍历,中序遍历,后序遍历,使用不同的方式代码去实现,并且后续遍历更为难理解一些 可拓展性更好(比如N叉树的遍历),也更容易理解 考虑,对于一个函数栈,它除了存储了一些变量和指令,同时还存储了当前执行位置. 对于树的遍历,无非为:t->val,t->left ,t->right