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

  1 /**
  2  * 二叉树的前序、中序、后序遍历的递归和非递归算法实现
  3  **/
  4
  5 //二叉链表存储
  6 struct BTNode
  7 {
  8     struct BTNode *LChild;    // 指向左孩子指针
  9     ELEMENTTYPE    data;      // 结点数据
 10     struct BTNode *RChild;    // 指向右孩子指针
 11 };
 12
 13 /**
 14  * 前序遍历
 15  **/
 16 // 递归实现
 17 void PreorderTraversal(BTNode *BT)
 18 {
 19     if(BT!=NULL) {
 20         Print(BT->data);                                // 访问根结点
 21         PreorderTraversal(BT->LChild);                  // 前序遍历左子树
 22         PreorderTraversal(BT->RChild);                  // 前序遍历右子树
 23     }
 24 }
 25
 26 // 非递归实现
 27 void PreorderTraversal(BTNode *BT)
 28 {
 29     InitStack(stack, treeDeepth);                       // 初始化元素为结点指针类型的栈stack,用以保存结点的指针
 30     BTNode *current = BT;                               // current指向但前要访问的结点,初始时指向根结点
 31     while(current != NULL || !EmptyStack(stack)) {      /* current为空结点且栈空,遍历结束 */
 32         if(current != NULL) {                           /* 若current不是空结点 */
 33             Print(current->data);                       // 访问current指向的结点
 34             Push(stack, current);                       // 当前结点指针current压栈
 35             current = current->LChild;                  // 使current的左孩子成为当前结点
 36         } else {                                        /* 若current指向的为空结点 */
 37             current = Pop(stack);                       // 弹出栈顶的结点指针赋给current
 38             current = current->RChild;                  // 使current的右孩子成为当前结点
 39         }
 40     }
 41 }
 42
 43 /**
 44  * 中序遍历
 45  **/
 46 // 递归实现
 47 void InorderTraversal(BTNode *BT)
 48 {
 49     if(BT!=NULL) {
 50         InorderTraversal(BT->LChild);                   // 中序遍历左子树
 51         Print(BT->data);                                // 访问根结点
 52         InorderTraversal(BT->RChild);                   // 中序遍历右子树
 53     }
 54 }
 55
 56 // 非递归实现
 57 void InorderTraversal(BTNode *BT)
 58 {
 59     InitStack(stack, treeDeepth);                       // 初始化元素为结点指针类型的栈stack,用以保存结点的指针
 60     BTNode *current = BT;                               // current指向但前要访问的结点,初始时指向根结点
 61     while(current != NULL || !EmptyStack(stack)) {      /* current为空结点且栈空,遍历结束 */
 62         if(current != NULL) {                           /* 若current不是空结点 */
 63             Push(stack, current);                       // 当前结点指针current压栈
 64             current = current->LChild;                  // 使current的左孩子成为当前结点
 65         } else {                                        /* 若current指向的为空结点 */
 66             current = Pop(stack);                       // 弹出栈顶的结点指针赋给current
 67             Print(current->data);                       // 访问current指向的结点
 68             current = current->RChild;                  // 使current的右孩子成为当前结点
 69         }
 70     }
 71 }
 72
 73 /**
 74  * 后序遍历
 75  **/
 76 // 递归实现
 77 void PostorderTraversal(BTNode *BT)
 78 {
 79     if(BT!=NULL) {
 80         PostorderTraversal(BT->LChild);                 // 后序遍历左子树
 81         PostorderTraversal(BT->RChild);                 // 后序遍历右子树
 82         Print(BT->data);                                // 访问根结点
 83     }
 84 }
 85
 86 // 非递归实现
 87 void PostorderTraversal(BTNode *BT)
 88 {
 89     InitStack(stack, treeDeepth);                       // 初始化元素为结点指针类型的栈stack,用以保存结点的指针
 90     BTNode *current = BT;                               // current指向但前要访问的结点,初始时指向根结点
 91     Push(stack, current);                               // 当前结点指针current压栈
 92     while(current->LChild != NULL) {                    /* 从当前结点出发,逐步找到二叉树左边结点并依次进栈 */
 93         current = current->LChild;
 94         Push(stack, current);
 95     }
 96     while(!EmptyStack(stack)) {                         /* 一直进行到栈空为止,整棵二叉树遍历完成 */
 97         current = Pop(stack);                           // 栈顶结点退栈作为当前结点
 98         if(current < 0) {                       /* 若当前结点指针标志为“负”,表示该结点的右子树已遍历完,应该访问该结点 */
 99             current = -current;                 /******* 对指针加正负号,OK,学习了,竟然这样子来标识 *******/
100             Print(current->data);
101         } else {                                /* 若当前结点标志为“正”,表示该结点的左子树已遍历完,应该遍历其右子树 */
102             Push(stack, -current);                      // 对当前结点指针加左子树已遍历标志并入栈
103             if(current->RChild != NULL) {               // 若当前结点有右子树,以右孩子作为当前结点,从它出发做后序遍历
104                 current = current->RChild;
105                 Push(stack, current);
106                 while(current->LChild != NULL) {
107                     current = current->LChild;
108                     Push(stack, current);
109                 }
110             }
111         }
112     }
113 }

二叉树的前序、中序、后序遍历的递归和非递归算法实现,布布扣,bubuko.com

时间: 2024-12-24 19:11:18

二叉树的前序、中序、后序遍历的递归和非递归算法实现的相关文章

二叉树的先序、中序、后序、层次遍历的递归和非递归解法

二叉树的先序.中序.后序.层次遍历的递归和非递归解法 package tree; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class TreeTraverse { /** * 先序递归 * @param root */ public static void preOrderTraverse(TreeNode root) { if (root == null) { ret

二叉树的三种遍历的递归与非递归算法

今天复习了一下二叉树的前序遍历.中序遍历.后序遍历的递归与非递归算法,顺便记录一下: //TreeTest.h #include <iostream> struct TreeNode { int value; TreeNode* leftChild; TreeNode* rightChild; void print() { printf("%d ",value); } }; class MyTree { private: TreeNode* m_root; TreeNode

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

二叉树的遍历有前序遍历.中序遍历.后序遍历.层次遍历等,笔者在这里总结一下各种遍历的实现. 一.前序遍历. 前序遍历访问节点顺序为:根节点->左子节点->右子节点. 递归实现如下: void preorder(TreeNode* root, vector<int>& nodes) { if (!root) return; nodes.push_back(root -> val); preorder(root -> left, nodes); preorder(r

【数据结构】二叉树(前、中、后)序遍历的递归与非递归算法

对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对 于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一 点. 二叉树前序:访问根节点->左子树->右子树 (1)递归写法: 依次访问根节点.左子树.右子树,注意递归出口的结束. void _PrevOrder(Node* root)     {         i

分别求二叉树前、中、后序的第k个节点

一.求二叉树的前序遍历中的第k个节点 //求先序遍历中的第k个节点的值 int n=1; elemType preNode(BTNode *root,int k){ if(root==NULL) return ' '; if(n==k) return root->data; n++; elemType ch = preNode(root->lchild,k); if(ch!=' ') return ch; ch = preNode(root->rchild,k); return ch;

算法实验-二叉树的创建和前序-中序-后序-层次 遍历

对于二叉树的创建我是利用先序遍历的序列进行创建 能够对于树节点的内容我定义为char型变量 '0'为空,即此处的节点不存在 头文件 Tree.h //链式二叉树的头文件 #pragma once #include<iostream> #include<queue> using namespace std; class BinaryTreeNode { public: char data; BinaryTreeNode *leftChild,*rightChild; BinaryTr

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

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

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

已知二叉树前、中序遍历,求后序 / 已知二叉树中、后序遍历,求前序

void solve(int start,int end,int root) { // 前序和中序 -> 后序 // 每次调用solve()函数,传入pre-order的start,end,root if (start > end) // 递归边界 return; int i = start; while (i < end && in.at(i) != pre.at(root)) // 找到左右子树的分割点 i++; solve(start, i - 1, root +