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

其中前序和中序,简单且容易理解。后序遍历有难度。

#include "stdafx.h"

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

typedef struct BiNode

{

char data;

struct BiNode *lchild,*rchild;

}BiNode,*LinkBiTree;

typedef struct stack

{

LinkBiTree *elem;//开辟空间去存贮链的结点,相当于是个顺序链表

int top;

int size;//顺序栈的大小,防止溢出

}SqStack;

//栈初始化

void InitStack(SqStack &s)

{

s.elem=(LinkBiTree*)malloc(sizeof(BiNode)*100);//给这个实例化的s的栈的元素分配100大小的空间;

s.top=-1;

s.size=100;

}

void push (SqStack &s,LinkBiTree e)

{

if (s.top==99)

printf("栈满!");

else

{

s.top++;

s.elem[s.top]=e;

}

}

LinkBiTree pop(SqStack &s,LinkBiTree e)

{

if(s.top==-1)

printf("栈空!");

else

{

e=s.elem[s.top];

s.top--;

}

return e;

}

//递归算法创建二叉树

void CreatTree(LinkBiTree &T)

{

char ch;

ch=getchar();

if(ch==‘#‘)

{

T=NULL;

return;

}

else

{

T=new BiNode;//链表式的二叉树,每一个结点都需要开辟空间给它

T->data=ch;

CreatTree(T->lchild);

CreatTree(T->rchild);

}

}

void preorder (LinkBiTree &T)

{

LinkBiTree p;//结点p

SqStack s;//栈s;

InitStack(s);//初始化栈

p=T;//同样类型的结点指针指向树结点;

if (T==NULL)//边界条件要考虑到啊

{

printf("空树!");}

while(p||!(s.top==-1))//树结点存在且栈不为空,因为不停的入栈出栈,直到所有结点都出栈才算完

{

if (p)

{

push(s,p);

printf("%c ",p->data);

p=p->lchild;//左子节点为空时,因为栈还不为空,循环会继续

}

else

{

p=pop(s,p);

p=p->rchild;

}

}

}

void midorder ( LinkBiTree &T)

{

LinkBiTree p;//结点p

SqStack s;//栈s;

InitStack(s);//初始化栈

p=T;//同样类型的结点指针指向树结点;

if (T==NULL)//边界条件要考虑到啊

{

printf("空树!");}

while(p||!(s.top==-1))//树结点存在且栈不为空,因为不停的入栈出栈,直到所有结点都出栈才算完

{

if (p)

{

push(s,p);

p=p->lchild;//左子节点为空时,因为栈还不为空,循环会继续

}

else

{

p=pop(s,p);

printf("%c ",p->data);

p=p->rchild;

}

}

}

void backorder(LinkBiTree &T)//后序遍历比较难

{

LinkBiTree p;//结点p

SqStack s;//栈s;

InitStack(s);//初始化栈

p=T;//同样类型的结点指针指向树结点;

int flag[100];//用于标记右子树是否已经访问。这是后序遍历难度的体现

if (T==NULL)//边界条件要考虑到啊

{

printf("空树!");

}

else

{

while (p!=NULL || s.top!=-1)

{

while (p!=NULL)

{

push(s,p);

flag[s.top]=0;

p=p->lchild;

}

while (!(s.top==-1)&&flag[s.top]==1)

{

p=pop(s,p);

printf("%c ",p->data);

}

if (!(s.top==-1))

{

flag[s.top]=1;   //设置标记右子树已经访问

p=s.elem[s.top];

p=p->rchild;

}

else break;

}

}

}

int main()

{

LinkBiTree t;

CreatTree(t);

printf("前序遍历:\n");

preorder(t);

printf("\n");

printf("中序遍历:\n");

midorder(t);

printf("\n");

printf("后序遍历:\n");

backorder(t);

system("pause");

return 0;

}

时间: 2024-10-17 11:03:25

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

二叉树的中序遍历(非递归)

中序遍历是先遍历左子树,在自身,再遍历右子树, 非递归实现的方法,一直遍历左节点,然后出栈,在遍历右节点 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def inorderTraversal(self, root

树——二叉树的后序遍历(非递归)

思路: 二叉树的后序遍历非递归方法与前序,中序不同,稍微麻烦一些. 要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点cur,先将其入栈.如果cur不存在左孩子和右孩子,则可以直接访问它:或者cur存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点.若非上述两种情况,则将cur的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问. 代码如下: /** * Definition for

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树先序遍历(非递归)

二叉树的先序遍历(非递归)特别简单 直接上代码,根节点先入栈,然后循环栈不为空,pop出来后让右节点和左节点分别入栈 # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution(object): def preorderTraversal(sel

二叉树高度,以及栈实现二叉树的先序,中序,后序遍历的非递归操作

求解二叉树的高度 树是递归定义的,所以用递归算法去求一棵二叉树的高度很方便. #include <iostream> #include <cstdio> using namespace std; struct Node { char data; Node *lchild; Node *rchild; }; void High(Node *T, int &h) { if (T == NULL) h = 0; else { int left_h; High(T->lchi

二叉树基本操作续二:前序、中序、后序遍历(非递归 迭代方式)

这里给出二叉树三种遍历方式的迭代实现代码.二叉树的递归实现使用系统栈入栈出栈,而非递归的迭代实现方法就是手动维护一个栈,来模拟递归的入栈出栈过程. 本文没有给出用户栈的代码,如果需要结合上篇的测试代码一起测试,则需要自己实现自己的栈,以及基本的pop.push等栈操作函数. 前序迭代遍历: 1 void iter_preorder(tree_pointer ptr) 2 { 3 //前序遍历:先遍历根节点,然后再分别遍历左右子树 4 int top = -1; 5 tree_pointer st

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

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

1 二叉树的前序遍历 对于每棵子树,先处理根,然后处理左子树,最后处理右子树.根最先访问,所以是前序遍历. 2 二叉树的中序遍历 对于每棵子树,先处理左子树,然后处理根,最后处理右子树.根中间访问,所以是中序遍历. 3 二叉树的后序遍历 对于每棵子树,先处理左子树,然后处理右子树,最后处理根.根最后访问,所以是后序遍历. 4 二叉树后序遍历的非递归实现 如果pre为NULL: 左右儿子都是NULL,那么自己出栈: 如果左儿子为NULL,右儿子不为NULL,右儿子进栈: 如果左儿子不为NULL,那

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

二叉树前序.后序和后序遍历(非递归实现) (1)前序     我们知道,前序遍历的顺序是根左右,当根节点不为空时,该节点才可以被打印.目前书上常见对树的遍历都是采用递归的方法实现的,我们知道递归必然会产生中断,也就是有现场信息的保存,如果要实现非递归,那么我们必须自己要有一个栈,用来保存现场信息. 我先给出实现的伪代码,稍后我将解释为什么需要这么做,为何要用到这些条件. 伪代码如下: 1 void PreOrderTraverse(BinaryTree root) 2 { 3    Binary