二叉树的几种递归和非递归式遍历:

#include <fstream>
#include <iostream>

using namespace std;

/*
后序遍历的非递归实现是三种遍历方式中最难的一种。因为在后序遍历中,要保证左孩子和右孩子都已被访问并且左孩子在右孩子
前访问才能访问根结点,这就为流程的控制带来了难题。下面介绍两种思路。
第一种思路:对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,
但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子
时,该结点又出现在栈顶,此时可以将其出栈并访问。这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现
在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
第二种思路:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种
情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结
点前面被访问。
*/

#define queue_len 100

struct node
{
char c;
struct node *lch,*rch;
bool flag;
node():flag(0){}
void get_c()
{
printf("%c",c);
}
};

node* set_tree();//建树
void pre_order(node* tree);//先序遍历
void in_order(node* tree);//中序遍历
void post_order(node* tree);//后序遍历
void level_order(node* tree);//层次遍历
void nr_pre_order(node* tree);//非递归先序遍历
void nr_in_order(node* tree);//非递归中序遍历
void nr_post_order_1(node* tree);//非递归后序遍历
void nr_post_order_2(node* tree);//非递归后序遍历

int main()
{
//freopen("D:\\input.in","r",stdin);
//freopen("D:\\output.out","w",stdout);
node* tree=set_tree();
printf("先序遍历:");
pre_order(tree);
puts("");
printf("中序遍历:");
in_order(tree);
puts("");
printf("后序遍历:");
post_order(tree);
puts("");
printf("层次遍历:");
level_order(tree);
puts("");
printf("先序遍历:");
nr_pre_order(tree);
puts("");
printf("中序遍历:");
nr_in_order(tree);
puts("");
printf("后序遍历:");
nr_post_order_1(tree);
puts("");
printf("后序遍历:");
nr_post_order_2(tree);
puts("");
return 0;
}
node* set_tree()
{
node* p,*s;
node* gen=new node;
gen->c=‘A‘;

gen->lch=new node;
p=gen->lch;
p->c=‘B‘;
p->rch=NULL;
p->lch=new node;
p=p->lch;
p->c=‘D‘;
p->lch=NULL;
p->rch=new node;
p=p->rch;
p->c=‘G‘;
p->lch=NULL;
p->rch=NULL;

gen->rch=new node;
p=gen->rch;
p->c=‘C‘;
p->lch=new node;
s=p->lch;
s->c=‘E‘;
s->lch=NULL;
s->rch=NULL;
p->rch=new node;
s=p->rch;
s->c=‘F‘;
s->lch=NULL;
s->rch=NULL;

return gen;
}
void pre_order(node* tree)
{
if(tree!=NULL)
{
tree->get_c();
pre_order(tree->lch);
pre_order(tree->rch);
}
}
void in_order(node* tree)
{
if(tree!=NULL)
{
in_order(tree->lch);
tree->get_c();
in_order(tree->rch);
}
}
void post_order(node* tree)
{
if(tree!=NULL)
{
post_order(tree->lch);
post_order(tree->rch);
tree->get_c();
}
}
void level_order(node* tree)
{
node* queue_1[queue_len];
int front,rear;

if(tree==NULL) return;
front=-1;
rear=0;
queue_1[rear]=tree;
while(front!=rear)
{
front++;
queue_1[front]->get_c();

if(queue_1[front]->lch!=NULL)
{
rear++;
queue_1[rear]=queue_1[front]->lch;
}
if(queue_1[front]->rch!=NULL)
{
rear++;
queue_1[rear]=queue_1[front]->rch;
}
}
}
void nr_pre_order(node* tree)
{
node* stack_1[queue_len];
int top=-1;

if(tree==NULL) return;
node* p=tree;
while(p!=NULL||top!=-1)
{
while(p!=NULL)
{
p->get_c();
stack_1[++top]=p;
p=p->lch;
}
if(top==-1) return;
p=stack_1[top--]->rch;
}
}
void nr_in_order(node* tree)
{
node* stack_1[queue_len];
int top=-1;

if(tree==NULL) return;
node* p=tree;
while(p!=NULL||top!=-1)
{
while(p!=NULL)
{
stack_1[++top]=p;
p=p->lch;
}
if(top==-1) return;
stack_1[top]->get_c();
p=stack_1[top--]->rch;
}
}
void nr_post_order_1(node* tree)
{
node* stack_1[queue_len];
int top=-1;

if(tree==NULL) return;
node* p=tree;
while(p!=NULL||top!=-1)
{
while(p!=NULL)
{
stack_1[++top]=p;
p=p->lch;
}
if(top==-1) return;
p=stack_1[top];
if(p->flag==0) {p->flag=1;p=p->rch;}
else { p->get_c(),top--;p=NULL;}
}
}
void nr_post_order_2(node* tree)
{
node* stack_1[queue_len];
int top=0;

if(tree==NULL) return;
node* p=tree;
while(top!=-1)
{
p=stack_1[top];
if((p->lch==NULL||p->lch->flag==0)&&(p->rch==NULL||p->rch->flag==0))
{
p->get_c();
p->flag=0;
top--;
}
else
{
if(p->rch!=NULL)
{
stack_1[++top]=p->rch;
}
if(p->lch!=NULL)
{
stack_1[++top]=p->lch;
}
}
}
}

时间: 2024-10-16 22:40:42

二叉树的几种递归和非递归式遍历:的相关文章

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree; import java.util.Stack; public class BiTree { public static void main(String[] args) { // 首先构造叶子节点 BiTree leafA1 = new BiTree(4); BiTree leafA2 = new BiTree(5); BiTree leafB1 = new BiTree(6); BiTree leafB2 = new BiTree(7)

二叉树三种遍历递归及非递归实现(Java)

import java.util.Stack; //二叉树三种遍历递归及非递归实现(Java) public class Traverse { /******************定义二叉树**************************/ private final int MAX_SIZE = 10; //链式存储 public static class BinaryTreeNode { int mValue; BinaryTreeNode mLeft; BinaryTreeNode

二叉树遍历递归与非递归实现

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程. 二叉树的遍历分为:前序遍历(也叫先序遍历).中序遍历.后序遍历.所谓前.中.后都是根据当前子树根结点相对左右孩子的位置而言,也就是说: 前序遍历:根结点在前,即:根 ----->左------->右: 中序遍历:根结点在中间,即:左------>根------>右: 后序遍历:根结点在最

二叉树遍历算法总结(递归与非递归)

一:前言 二叉树的遍历方法分四种:前序,中序,后序以及层次遍历. 其中,前中后遍历方法的实现分递归和非递归,非递归遍历的实现需要借助于栈. 实际上,递归的调用就是一种栈的实现,所以,非递归遍历就需要人工借助栈结构来实现. 而层次遍历需要借助队列. 二:前中后序遍历 递归遍历: 递归遍历的思想和方法很简单,通过调整输出语句来实现前,中,后三种遍历. 代码如下: 1 void show(BiTree T) 2 { 3 if(T) 4 { 5 printf("%c ",T->data)

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

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

二叉树的递归和非递归遍历

// 本次练习的是  二叉树的  递归和非递归  遍历   以及二叉树的  节点数  高度  叶子节点数   和查找功能  //如果要是变量在函数栈回归时不回归原值,则可以用引用// #define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<stack>#include<queue>using namespace std; template<class T>struct BinaryTreeNod

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

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

C实现二叉树(模块化集成,遍历的递归与非递归实现)

C实现二叉树模块化集成 实验源码介绍(源代码的总体介绍):header.h : 头文件链栈,循环队列,二叉树的结构声明和相关函数的声明.LinkStack.c : 链栈的相关操作函数定义.Queue.c : 循环队列的相关操作函数定义.BinTree.c : 二叉树的相关操作的函数定义,层序序列生成二叉树,二叉树的前序序列.中序序列.后序序列的递归和非递归实现,求叶子结点的递归与非递归实现,求树高.我目前还是新手且第一次写类似的博客,文章中难免会有错误!如发现错误,望各路大神能够指出!详见源代码

数据结构二叉树的递归与非递归遍历之 实现可编译(1)java

前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序遍历为例进行说明,中序遍历和后序遍历,以此类推! 二叉树递归与非递归遍历的区别,虽然递归遍历,跟容易读懂,代码量少,运算快,但是却容易出现溢出的问题,所以所以非递归遍历,在处理千万级的运算量时会先的很有用处. 二叉树的先序遍历:先访问根节点,再访问先后访问左右节点.如图: 二叉树的递归遍历之java

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {