二叉树的遍历

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的遍历相关的知识,希望对你有一定的参考价值。




求 (1)建立一颗二叉树;
(2)用递归方式对二叉树进行先序、中序和后序遍历,输出遍历结果;
(3)用非递归方式对二叉树进行先序、中序和后序遍历,输出遍历结果;

用C++或C语言实现设计任务;

帮帮忙。。。明天要用,着急呀!在线等。。。完成以后200分都行。。。先给30

参考技术A //二叉树基本操作
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define NULL 0
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1

typedef int Status;
typedef char TElemType;
typedef struct BiTNode
TElemType data;
struct BiTNode *lchild,*rchild;
BiTNode,*BiTree,*SElemType;
typedef struct
SElemType *base;
SElemType *top;
int stacksize;
SqStack;

Status InitStack (SqStack &S)
//构造空栈并初始化
S.base=(SElemType * )malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!S.base) exit(OVERFLOW);//存储分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;


Status StackEmpty(SqStack S)
//判断是否为空栈,是返回TRUE,不是返回FALSE
if(S.base==S.top)
return TRUE;
else
return FALSE;


Status Push(SqStack &S,BiTree e)
//将元素e压入栈顶
if(S.top-S.base>=S.stacksize)
//栈满,追加存储空间
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof (SElemType));
if(!S.base)exit(OVERFLOW);//存储分配失败
S.top=S.base+S.stacksize;
S.stacksize +=STACKINCREMENT;

*S.top++=e;
return OK;


Status Pop(SqStack &S,SElemType &e)
//删除栈顶元素,用e返回其值,并返回OK,否则返回ERROR
if(S.top==S.base) return ERROR;//空栈情况
e=*--S.top;
return OK;


Status InitBiTree(BiTree &T)
//构造空二叉树T
T=NULL;
return OK;


BiTree CreateBiTree(BiTree &T)
//按先序次序输入二叉树中结点的值,空格字符表示空树
//构造二叉链表表示的二叉树T
char ch;
scanf("%c",&ch);
if (ch=='.') T=NULL;
else
if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);

return T;

Status PrintElement(TElemType e)
//输出元素e的值
printf("%c",e);
return OK;


Status PreOrderTraverse(BiTree T,Status (* Visit)(TElemType e))
//先序遍历二叉树T的递归算法
if(T)
if(Visit(T->data))
if(PreOrderTraverse(T->lchild,Visit))
if(PreOrderTraverse(T->rchild,Visit))
return OK;
return ERROR;
else return OK;


void InOrderTraverse(BiTree bt)
//中序遍历二叉树的递归算法
if (bt)
InOrderTraverse(bt->lchild);/* 中序遍历根结点 */
printf("%c",bt->data); /* 访问根结点 */
InOrderTraverse(bt->rchild); /* 中序遍历右子树*/

/* inorder */

void PostOrderTraverse(BiTree bt)
//后序遍历二叉树的递归算法
if(bt)
PostOrderTraverse(bt->lchild); /* 后序遍历根结点 */
PostOrderTraverse(bt->rchild);/* 访问根结点 */
printf("%c",bt->data); /* 后序遍历右子树*/

/* Postorder*/

Status InOrderTraverse2(BiTree T, Status (*Visit)(TElemType))
// 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
// 中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit。
SqStack S;
BiTree p;
InitStack(S); p = T;
while (p || !StackEmpty(S)) //P或stack不为空
if (p)
Push(S, p);
p = p->lchild;
// 非空指针进栈,继续左进
else // 上层指针退栈,访问其所指结点,再向右进
Pop(S, p); //弹栈,将p指向被弹结点
if (!Visit(p->data)) //所访问结点不存在
return ERROR;
p = p->rchild;


return OK;
// InOrderTraverse

void main()

BiTree T;
InitBiTree(T);
printf("创建二叉树T,空树用.代替:\n");
CreateBiTree(T);
printf("先序遍历二叉树:");
PreOrderTraverse(T,PrintElement);
printf("\n");
printf("递归算法中序遍历二叉树:");
InOrderTraverse(T);
printf("\n非递归算法中序遍历二叉树:");
InOrderTraverse2(T,PrintElement);
printf("\n后序遍历二叉树:");
PostOrderTraverse(T);
printf("\n");
本回答被提问者采纳
参考技术B 搜一下,这样的遍历的简单递归的例子很多追问

请给出完整的程序。。。。。

追答

自已搜呀,这样 的问题不知有多少重复的

Java实现二叉树的创建递归/非递归遍历

近期复习数据结构中的二叉树的相关问题,在这里整理一下

这里包含:
1、二叉树的先序创建

2、二叉树的递归先序遍历

3、二叉树的非递归先序遍历

4、二叉树的递归中序遍历

5、二叉树的非递归中序遍历

6、二叉树的递归后序遍历

7、二叉树的非递归后序遍历

8、二叉树的层次遍历

这里感谢博客http://blog.csdn.net/skylinesky/article/details/6611442的指导


/**二叉树的结点定义*/
class Node<T>{
	private T value;
	private Node<T> left;
	private Node<T> right;
	
	public Node(){
	}
	public Node(Node<T> left, Node<T> right, T value){
		this.left = left;
		this.right = right;
		this.value = value;
	}
	public Node(T value){
		this(null, null, value);
	}
	
	public Node<T> getLeft(){
		return this.left;
	}
	public void setLeft(Node<T> left){
		this.left = left;
	}
	public Node<T> getRight(){
		return this.right;
	}
	public void setRight(Node<T> right){
		this.right = right;
	}
	public T getValue(){
		return this.value;
	}
	public void setValue(T value){
		this.value = value;
	}
}


import java.io.File;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * 二叉树的定义:或为空,或仅仅有根节点,或有左子树和右子树(5种基本形态)
 * 二叉树性质:
 * 1、在二叉树的第i层上至多有2^(i-1)个结点(i>=1)
 * 2、深度为k的二叉树至多有2^(k) - 1个结点(k>=1)
 * 3、对于不论什么一颗二叉树,假设其终端结点数为n,度数为2的结点数为m。则n = m + 1
 * 4、具有n个结点的全然二叉树的深度为k = floor(log2(n)) + 1
 * 5、在含有n个结点的二叉链表中有n+1个空链域
 * 
 * @author 小菜鸟
 *创建时间:2014-08-10
 */

public class BinaryTree<T> {

	/**二叉树的根节点*/
	private Node<T> root;
	
	public BinaryTree(){}
	public BinaryTree(Node<T> root){
		this.root = root;
	}
	
	/**先序遍历创建二叉树*/
	/**input.txt: - + a # # * # # / e # # f # #
	 * # 代表空结点
	 */
	public void createBiTree(){
		Scanner scn = null;
		
		try {
			scn = new Scanner(new File("input.txt"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		this.root = createBiTree(root, scn);
	}
	private Node<T> createBiTree(Node<T> node, Scanner scn) {
		
		String temp = scn.next();
		if(temp.trim().equals("#")){
			return null;
		}
		else{
			node = new Node<T>((T)temp);
			node.setLeft(createBiTree(node.getLeft(), scn));
			node.setRight(createBiTree(node.getRight(), scn));
			return node;
		}
	}
	
	/**先序递归遍历二叉树*/
	public void preOrderTraverse(){
		preOrderTraverse(root);
	}
	private void preOrderTraverse(Node<T> node) {
		if(node != null){
			System.out.println(node.getValue());
			preOrderTraverse(node.getLeft());
			preOrderTraverse(node.getRight());
		}
	}
	
	
	/**先序非递归遍历二叉树*/
	public void nrPreOrderTraverse(){
		Stack<Node<T>> stack = new Stack<Node<T>>();
		Node<T> node = root;
		while(node != null || !stack.isEmpty()){
			while(node != null){
				System.out.println(node.getValue());
				stack.push(node);
				node = node.getLeft();
			}
			node = stack.pop();
			node = node.getRight();
		}
	}
	
	
	
	/**中序递归遍历二叉树*/
	public void inOrderTraverse(){
		inOrderTraverse(root);
	}
	private void inOrderTraverse(Node<T> node) {
		if(node != null){
			inOrderTraverse(node.getLeft());
			System.out.println(node.getValue());
			inOrderTraverse(node.getRight());
		}
	}
	
	/**中序非递归遍历二叉树*/
	public void nrInOrderTraverse(){
		Stack<Node<T>> stack = new Stack<Node<T>>();
		Node<T> node = root;
		while(node != null || !stack.isEmpty()){
			while(node != null){
				stack.push(node);
				node = node.getLeft();
			}
			node = stack.pop();
			System.out.println(node.getValue());
			node = node.getRight();
		}
	}
	
	/**后序递归遍历二叉树*/
	public void postOrderTraverse(){
		postOrderTraverse(root);
	}
	private void postOrderTraverse(Node<T> node) {
		if(node != null){
			postOrderTraverse(node.getLeft());
			postOrderTraverse(node.getRight());
			System.out.println(node.getValue());
		}
	}
	
	/**后序非递归遍历二叉树*/
	public void nrPostOrderTraverse(){
		Stack<Node<T>> stack = new Stack<Node<T>>();
		Node<T> node = root;
		Node<T> preNode = null;	//记录之前遍历的右结点
		while(node != null || !stack.isEmpty()){
			while(node != null){
				stack.push(node);
				node = node.getLeft();
			}
			node = stack.getTop();
			
			/**假设右结点为空,或者右结点之前遍历过。打印根结点*/
			if(node.getRight() == null || node.getRight() == preNode){
				System.out.println(node.getValue());
				node = stack.pop();
				preNode = node;
				node = null;
			}
			else{
				node = node.getRight();
			}
		}
	}
	
	
	/**层次遍历二叉树*/
	public void levelTraverse(){
		levelTraverse(root);
	}
	private void levelTraverse(Node<T> node) {
		Queue<Node<T>> queue = new Queue<Node<T>>();
		queue.push(node);
		while(!queue.isEmpty()){
			node = queue.pop();
			if(node != null){
				System.out.println(node.getValue());
				queue.push(node.getLeft());
				queue.push(node.getRight());
			}
		}
	}
	
	
	public static void main(String[] args){
		BinaryTree<String> bt = new BinaryTree<String>();
		bt.createBiTree();
		//bt.preOrderTraverse();
		//bt.inOrderTraverse();
		//bt.postOrderTraverse();
		//bt.nrPreOrderTraverse();
		//bt.nrInOrderTraverse();
		//bt.nrPostOrderTraverse();
		bt.levelTraverse();
	}
}



【注:当中关于栈和队列的定义请參考还有一篇博文】

Java实现栈和队列的定义:http://blog.csdn.net/junwei_yu/article/details/38470825








以上是关于二叉树的遍历的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的后续遍历是啥意思啊?

二叉树的遍历

为啥树的后根遍历对应二叉树的中序遍历

二叉树 详解

图解 二叉树的四种遍历

二叉树的遍历