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

说明:本文仅供学习交流,转载请标明出处,欢迎转载!

二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程。

二叉树的遍历分为:前序遍历(也叫先序遍历)、中序遍历、后序遍历。所谓前、中、后都是根据当前子树根结点相对左右孩子的位置而言,也就是说:

前序遍历:根结点在前,即:根 ----->左------->右;

中序遍历:根结点在中间,即:左------>根------>右;

后序遍历:根结点在最后,即:左------->右------根。

从上面的定义可以看出,这三种遍历中,左子树总是比右子树优先访问。

下图是我们给一个例子:

代码如下:

#include<iostream>
#include<stack>
using namespace std;
struct Node
{
	int data;
	Node *left;
	Node *right;
	bool FirstVisited;
	Node(int data)
	{
		this->data=data;
		this->left=NULL;
		this->right=NULL;
		FirstVisited=true;
	}
};
class BinTree
{
public:
	Node *root;
	Node* CreateTree();
	void preOrder(Node *r);//递归实现先序遍历
	void preOrder1(Node *r);//先序遍历非递归实现

	void InOrder(Node *r);//递归实现中序遍历
	void InOrder1(Node *r);//中序遍历的非递归实现

	void PostOrder(Node *r);//递归实现后续遍历
	void PostOrder1(Node *r);//后序遍历非递归算法
};

Node* BinTree::CreateTree()//创建一棵二叉树
{
	Node *p1=new Node(1);
	Node *p2=new Node(2);
	Node *p3=new Node(3);
	Node *p4=new Node(4);
	Node *p5=new Node(5);
	Node *p6=new Node(6);
	Node *p7=new Node(7);
	Node *p8=new Node(8);
	Node *p9=new Node(9);
	p1->left=p2;
	p1->right=p3;
	p2->left=p4;
	p2->right=p5;
	p5->left=p6;
	p3->left=p7;
	p3->right=p8;
	p8->right=p9;
	root=p1;
	return p1;
}

void BinTree::preOrder(Node *r)//递归实现先序遍历
{
	if(r==NULL)
	{
		return ;
	}
	else
	{
		cout<<r->data<<" ";
		preOrder(r->left);
		preOrder(r->right);
	}
}
void BinTree::preOrder1(Node *root)//先序遍历的非递归实现
{
	if(root!=NULL)
	{
		Node *p=root;
		stack<Node*>s;
		while(p!=NULL ||!s.empty())
		{
			while(p)
			{
				cout<<p->data<<" ";
				s.push(p);
				p=p->left;
			}
			if(!s.empty())
			{
				if(s.top()->right)//如果最左端的结点有右孩子
				{
					p=s.top()->right;
				}
				s.pop();//出栈
			}
		}
	}
	cout<<endl;
}

void BinTree::InOrder(Node *r)//递归实现中序遍历
{
	if(r==NULL)
	{
		return ;
	}
	else
	{
		InOrder(r->left);
		cout<<r->data<<" ";
		InOrder(r->right);
	}
}

void BinTree::InOrder1(Node *r)//中序遍历的非递归实现
{
	if(r!=NULL)
	{
		Node *p=r;
		stack<Node*>s;
		while(p || !s.empty())
		{
			while(p)
			{
				s.push(p);
				p=p->left;
			}
			if(!s.empty())
			{
				Node *q=s.top();
				cout<<q->data<<" ";
				s.pop();
				if(q->right)
				{
					p=q->right;
				}
			}
		}
	}
	cout<<endl;
}

void BinTree::PostOrder(Node *r)//递归实现后序遍历
{
	if(r==NULL)
	{
		return ;
	}
	else
	{
		PostOrder(r->left);
		PostOrder(r->right);
		cout<<r->data<<" ";
	}
}

void BinTree::PostOrder1(Node *r)//后序遍历的非递归实现
{
	if(r==NULL)
		return ;
	Node *p=r;
	stack<Node*>s;
	while(p || !s.empty())
	{
		while(p)//先将所有的左孩子压入栈中
		{
			s.push(p);
			p=p->left;
		}
		if(!s.empty())
		{
			Node *q=s.top();
			if(q->FirstVisited)//如果是第一次访问
			{
				q->FirstVisited=false;
				p=q->right;
			}
			else//如果是第二次访问,则输出
			{
				cout<<q->data<<" ";
				s.pop();
				p=NULL;//给p一条出路
			}

		}
	}
}
int main()
{
	BinTree t;
	t.CreateTree();//创建二叉树
	/////////////三种遍历方式//////////////
	cout<<"先序遍历:";
	t.preOrder(t.root);//先序遍历
	cout<<endl<<"先序遍历非递归实现算法:";
	t.preOrder1(t.root);
	cout<<endl;

	cout<<"中序遍历:";
	t.InOrder(t.root);//中序遍历
	cout<<endl<<"中序遍历非递归算法:";
	t.InOrder1(t.root);
	cout<<endl;

	cout<<"后序遍历:";
	t.PostOrder(t.root);//后序遍历
	cout<<endl<<"后序遍历的非递归算法:";
	t.PostOrder1(t.root);//后序遍历的非递归算法
	cout<<endl;
	return 0;
}

测试结果如下:

二叉树遍历递归与非递归实现,布布扣,bubuko.com

时间: 2024-10-26 07:17:55

二叉树遍历递归与非递归实现的相关文章

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) {

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

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

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)

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

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

二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream> #include <stack> using namespace std; #define MAX 100 //字符串最大长度 typedef struct Node //二叉树结点 { char data; Node *lchild,*rchild; } *Btree; void createBT(Btree &t); //先序构造二叉树 void preorder(Btree &t); //二叉树递归先序遍历 void i

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

本文部分来源于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

二叉树遍历(递归与非递归)

/*二叉树遍历(递归版本&非递归版本)(1)中序遍历(2)先序遍历(3)后续遍历*/ struct BinTree { int data; /*数据域*/ BinTree* leftchild; /*左孩子*/ BinTree* rightchild; /*右孩子*/};/*中序遍历(递归版本)*/void InOrder(BinTree* root){ if(root){ InOrder(root->leftchild); cout << root->data; InOr