数据结构-二叉树的各种遍历(先中后层序!!)

最近在写数据结构中二叉树的遍历,这里总结一下:

先序递归遍历:

void PreTravel(BiTree T)
{//前序递归遍历
	if(T)
	{
		printf("%c",T->data);
		PreTravel(T->lchild);
		PreTravel(T->rchild);
	}
}

中序递归遍历:

void MidTravel(BiTree T)
{//中序递归遍历
	if(T)
	{
		MidTravel(T->lchild);
		printf("%c",T->data);
		MidTravel(T->rchild);
	}
}

后序递归遍历:

void PostTravel(BiTree T)
{//后序递归遍历
	if(T)
	{
		PostTravel(T->lchild);
		PostTravel(T->rchild);
		printf("%c",T->data);
	}
}

先序非递归遍历:

void PreOrder(BiTree &T)
{//先序非递归遍历
	stack<BiTree> s;
	BiTree p = T;
	while(p || !s.empty())
	{
		if(p)
		{
			printf("%c", p->data);
			s.push(p);
			p = p->lchild;
		}
		else
		{
			p = s.top();
			s.pop();
			p = p->rchild;
		}
	}
} 

中序非递归遍历:

void InOrder(BiTree T)
{//中序非递归遍历
	stack<BiTree> s;
	BiTree p = T;
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			p = p->lchild;
		}
		else
		{
			p = s.top();
			printf("%c", p->data);
			s.pop();
			p = p->rchild;
		}
	}
} 

后序非递归遍历:

void PostOrder(BiTree &T)
{//后序非递归遍历(加入一个标志变量visit,判断左右子树是否进栈)
	stack<BiTree> s;
	BiTree p = T;
	p->visit = false;
	if(T) s.push(T);
	while(!s.empty())
	{
		p = s.top();
		if(p->visit)
		{
			printf("%c", p->data);
			s.pop();
		}
		else
		{
			if(p->rchild)
			{
				p->rchild->visit = false;
				s.push(p->rchild);
			}
			if(p->lchild)
			{
				p->lchild->visit = false;
				s.push(p->lchild);
			}
			p->visit = true;
		}
	}
}

void PostOrder1(BiTree &T)
{//后序非递归遍历 (销毁了树的结构,不可取)
	stack<BiTree> s;
	BiTree q, p = T;
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			q = p;
			p = q->lchild;
			q->lchild = NULL;
		}
		else
		{
			q = s.top();
			p = q->rchild;
			q->rchild = NULL;
			if(p)
			{
				s.push(p);
				q = p;
				p = q->lchild;
				q->lchild = NULL;
			}
			else
			{
				p = s.top();
				printf("%c", p->data);
				s.pop();
				if(!s.empty())
				{
					p = s.top();
					p = p->lchild;
				}
				else return;
			}
		}
	}
} 

层序遍历:

void LevelOrder(BiTree &T)
{//层序遍历
	queue<BiTree> q;
	q.push(T);
	BiTree p;
	while(!q.empty())
	{
		p = q.front();
		printf("%c", p->data);
		q.pop();
		if(p->lchild)
			q.push(p->lchild);
		if(p->rchild)
			q.push(p->rchild);
	}
}

主函数调用:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <stack>
#include <queue>
#include "constant.h"
using namespace std;

typedef struct BiTNode
{
	char data;
	bool visit;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

void Print(char a)
{
	printf("%c", a);
	return;
}

void CreatBiTree(BiTree &T)
{//前序法创建二叉树
	char ch;
	if((ch=getchar())=='#')
		T=NULL;
	else
	{
		T=(BiTNode*)malloc(sizeof(BiTNode));
		if(!T)
			exit(1);
		T->data=ch;
		CreatBiTree(T->lchild);
		CreatBiTree(T->rchild);
	}
}

void PreTravel(BiTree T)
{//前序递归遍历
	if(T)
	{
		printf("%c",T->data);
		PreTravel(T->lchild);
		PreTravel(T->rchild);
	}
}

void MidTravel(BiTree T)
{//中序递归遍历
	if(T)
	{
		MidTravel(T->lchild);
		printf("%c",T->data);
		MidTravel(T->rchild);
	}
}

void PostTravel(BiTree T)
{//后序递归遍历
	if(T)
	{
		PostTravel(T->lchild);
		PostTravel(T->rchild);
		printf("%c",T->data);
	}
}

void PreOrder(BiTree &T)
{//先序非递归遍历
	stack<BiTree> s;
	BiTree p = T;
	while(p || !s.empty())
	{
		if(p)
		{
			printf("%c", p->data);
			s.push(p);
			p = p->lchild;
		}
		else
		{
			p = s.top();
			s.pop();
			p = p->rchild;
		}
	}
} 

void InOrder(BiTree T)
{//中序非递归遍历
	stack<BiTree> s;
	BiTree p = T;
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			p = p->lchild;
		}
		else
		{
			p = s.top();
			printf("%c", p->data);
			s.pop();
			p = p->rchild;
		}
	}
} 

void PostOrder(BiTree &T)
{//后序非递归遍历(加入一个标志变量visit,判断左右子树是否进栈)
	stack<BiTree> s;
	BiTree p = T;
	p->visit = false;
	if(T) s.push(T);
	while(!s.empty())
	{
		p = s.top();
		if(p->visit)
		{
			printf("%c", p->data);
			s.pop();
		}
		else
		{
			if(p->rchild)
			{
				p->rchild->visit = false;
				s.push(p->rchild);
			}
			if(p->lchild)
			{
				p->lchild->visit = false;
				s.push(p->lchild);
			}
			p->visit = true;
		}
	}
}

void PostOrder1(BiTree &T)
{//后序非递归遍历 (销毁了树的结构,不可取)
	stack<BiTree> s;
	BiTree q, p = T;
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			q = p;
			p = q->lchild;
			q->lchild = NULL;
		}
		else
		{
			q = s.top();
			p = q->rchild;
			q->rchild = NULL;
			if(p)
			{
				s.push(p);
				q = p;
				p = q->lchild;
				q->lchild = NULL;
			}
			else
			{
				p = s.top();
				printf("%c", p->data);
				s.pop();
				if(!s.empty())
				{
					p = s.top();
					p = p->lchild;
				}
				else return;
			}
		}
	}
} 

void LevelOrder(BiTree &T)
{//层序遍历
	queue<BiTree> q;
	q.push(T);
	BiTree p;
	while(!q.empty())
	{
		p = q.front();
		printf("%c", p->data);
		q.pop();
		if(p->lchild)
			q.push(p->lchild);
		if(p->rchild)
			q.push(p->rchild);
	}
}

int main()
{
	BiTree T;
	printf("please input the bitree:\n" );
    CreatBiTree(T);
	printf("The Pretravel is:\n");
	PreTravel(T);
	printf("\n");
	PreOrder(T);
	printf("\n");
	printf("The Midtravel is:\n");
	MidTravel(T);
	printf("\n");
	InOrder(T);
	printf("\n");
	printf("The PostTravel is:\n");
	PostTravel(T);
	printf("\n");
	PostOrder(T);
	printf("\n");
	printf("The LevelTravel is:\n");
	LevelOrder(T);
	printf("\n");

	PostOrder1(T);
	printf("\n");
	return 0;
}
时间: 2024-10-13 02:21:32

数据结构-二叉树的各种遍历(先中后层序!!)的相关文章

已知二叉树的前序遍历和中序遍历,如何得到它的后序遍历?

对一棵二叉树进行遍历,我们可以采取3中顺序进行遍历,分别是前序遍历.中序遍历和后序遍历.这三种方式是以访问父节点的顺序来进行命名的.假设父节点是N,左节点是L,右节点是R,那么对应的访问遍历顺序如下: 前序遍历    N->L->R 中序遍历    L->N->R 后序遍历    L->R->N /***************************************************************************************

002.深入浅出理解[二叉树的构建、先中后序遍历、树的深度、左右子树互换]

二叉树本来就是递归定义的,如果对递归还不是特别了解,建议看一下<001.深入浅出解释[递归]> 写一个递归函数很简单,只需要记住下面2点: 1.递归中止条件:对于二叉树来说一般是node==null的时候判断到了叶子结点 2.递归函数::描述一个中间过程,然后用代码实现,调用自身的时候传递的参数就是你想要递归的方式. 下面的代码就是一个二叉树的创建.先中后序遍历.树的深度.左右子树的互换的过程 #include <stdio.h> // 定义二叉树的结点 struct treeNo

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

输入某二叉树的前序遍历和中序遍历的结果,重建出该二叉树

//================================================================== // <剑指Offer--名企面试官精讲典型编程题>代码 // 作者:何海涛 //================================================================== // 面试题7:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

N4-某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. //本题思路参考另一个大神写的代码 其原地址为:https://www.nowcoder.com/profile/566744/codeBookDetail?submissionId=1516321 /** * 输入某二叉树的前序遍历和中序遍历的结果,

已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或者后序遍历的最后一个结点,查找对应在中序遍历中的位置,就可以确定左子树包含的元素和右子树包含的元素,最后通过递归来实现就可以了. 二叉树的表示形式为 //二叉树的结构表示为 class TreeNode { int val; TreeNode left; TreeNode right; TreeNo

学习日志---非递归二叉树游标遍历(前中后层序)

实现: //二叉树类 public class MyBiTree { private MyBiTreeNode  root;//根节点 MyBiTree() { this.root = null; } MyBiTree(Object data,MyBiTree left,MyBiTree right) { MyBiTreeNode l,r; if(left==null) { l = null; } else {    l=left.root;  } if(right==null) { r = n

二叉树的建立及其前中后序遍历

1 //二叉树存储结构: 2 struct node 3 { 4 Int data; 5 node *lchild; 6 node *rchild; 7 }; 8 9 //二叉树在建树前根节点不存在: 10 Node *root = NULL; 11 12 //新建结点: 13 node *newNode(int v) 14 { 15 node *Node = new node; 16 Node->data = v; 17 Node->lchild = NULL; 18 Node->rc