DS之遍历二叉树

在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点,或者对树中全部结点逐一进行某种处理。这就提出了一个遍历二叉树的问题,即如何按某条搜索路径巡访树中的每个结点,使得每个结点均被访问一次,而且仅被访问一次。

由二叉树的递归定义可知,二叉树是由三个基本单元构成的:根结点,左子树和右子树。若能依次遍历这三部分,便是遍历了整个二叉树。若限定先左后右的顺序,则遍历二叉树通常有三种算法:先序,中序,后序。

先序遍历二叉树的操作定义为:

若二叉树为空,则空操作;否则;

(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。

中序遍历二叉树的操作定义为:

若二叉树为空,则空操作;否则;

(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。

后序遍历二叉树的操作定义为:

若二叉树为空,则空操作;否则;

(1)后序遍历左子树;(2)后序遍历右子树;(3)访问根结点。

对于二叉树的遍历我们在二叉树的二叉链表上实现。在二叉树的二叉链表的基本操作中也介绍了四种遍历方法,我们就来实现前三种遍历方法。在遍历函数的参数中除了一个指针参数外,还有一个指向函数的指针参数。这个函数最简单的实现为Visit()函数。这个函数最简单的代码为:

Status printElement(TElemType e)//最简单的Visit()函数
{
	cout<<e<<",";
	return OK;
}

再者就是需要构建二叉表(先序输入数据元素)的代码:

Status CreateBiTree(BiTree &T)//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,构造二叉链表表示的二叉树T
{
	int i=0;
    char a[100];
    cin>>a[i];
    if(a[i]=='#') T=NULL;
    else
	{
         if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
		 {
				  exit(OVERFLOW);
		 }
         T->data=a[i];//生成根结点
         CreateBiTree(T->lchild);   //构造左子树
         CreateBiTree(T->rchild);   //构造右子树
    }
    return OK;
}

先来看看二叉链表的先序遍历代码:

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

再来看二叉链表的中序遍历代码:

Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//中序遍历二叉树
{
     if(T)
	 {
         if(InOrderTraverse(T->lchild,Visit))
         {
			 if(Visit(T->data))
			 {
                   if(InOrderTraverse(T->rchild,Visit))
				   {
					   return OK;
				   }
			 }
            return ERROR;
		  }
      }
	 else
	 {
	    return OK;
	 }
}

最后来看二叉链表的后序遍历代码:

Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//后序遍历二叉树
{
    if(T)
	{
       if(PostOrderTraverse(T->lchild,Visit))
       {
		  if(PostOrderTraverse(T->rchild,Visit))
          {
			  if(Visit(T->data))
              {
				return OK;
			  }
		   }
          return ERROR;
	    }
    }
	else
	{
	   return OK;
	}
}

完整的代码为:

#include <iostream>
#include <Cstdlib>
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW  -2

typedef char TElemType;
typedef int Status;

typedef struct BiTNode
{
   TElemType   data;
   struct  BiTNode   *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;

Status CreateBiTree(BiTree &T)//按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树,构造二叉链表表示的二叉树T
{
	int i=0;
    char a[100];
    cin>>a[i];
    if(a[i]=='#') T=NULL;
    else
	{
         if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
		 {
				  exit(OVERFLOW);
		 }
         T->data=a[i];//生成根结点
         CreateBiTree(T->lchild);   //构造左子树
         CreateBiTree(T->rchild);   //构造右子树
    }
    return OK;
}

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

Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//中序遍历二叉树
{
     if(T)
	 {
         if(InOrderTraverse(T->lchild,Visit))
         {
			 if(Visit(T->data))
			 {
                   if(InOrderTraverse(T->rchild,Visit))
				   {
					   return OK;
				   }
			 }
            return ERROR;
		  }
      }
	 else
	 {
	    return OK;
	 }
}

Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//后序遍历二叉树
{
    if(T)
	{
       if(PostOrderTraverse(T->lchild,Visit))
       {
		  if(PostOrderTraverse(T->rchild,Visit))
          {
			  if(Visit(T->data))
              {
				return OK;
			  }
		   }
          return ERROR;
	    }
    }
	else
	{
	   return OK;
	}
}

Status printElement(TElemType e)//最简单的Visit()函数
{
	cout<<e<<",";
	return OK;
}
int main()
{
    BiTree T;//构建二叉树
    CreateBiTree(T);//先序输入二叉树的数据元素
	cout<<"先序遍历二叉树的输出:";
    PreOrderTraverse(T,printElement);
    cout<<endl;
	cout<<"中序遍历二叉树的输出:";
	InOrderTraverse(T,printElement);
    cout<<endl;
	cout<<"后序遍历二叉树的输出:";
    PostOrderTraverse(T,printElement);
    cout<<endl;
	return 0;
}

输入的数据:先序输入ABC##DE#G##F###(#代表空)

这棵树的图为:

输出的结果为:

时间: 2024-11-15 22:29:06

DS之遍历二叉树的相关文章

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

非递归实现遍历二叉树

非递归实现二叉树主要利用queue和stack的特点,对于层次遍历二叉树主要运用queue队头出,队尾插入,先进先出的特点,先将根插入队尾,然后输出队头的元素,同时将队头的左子树和右子树元素插入队尾,依次输出输出队头的元素,同时将队头的左子树和右子树元素插入队尾,直到队列为空. void levelorder() { queue<BinaryTreeNode<T> *>s; if (_root == NULL) return; s.push(_root); while (!s.em

递归遍历二叉树

递归遍历分三种: 1.前序遍历二叉树(二叉树非空) 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 2.中序遍历二叉树(二叉树非空) 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 3.后序遍历二叉树(二叉树非空) 1.后序遍历左子树 2.后序遍历右子树 3.访问根节点 三种递归的算法遍历,终止条件是二叉树为空的时候. 记忆的方法呢,前中后,都是以根节点命名的,前序,先访问根节点,中序,根节点在第二,后序,根节点最后进行访问.

TAOCP_2.3.1_遍历二叉树

1. 算法T(以中根序遍历二叉树) 设$T$是指向二叉树的指针:本算法以中根序访问二叉树中的所有节点,并且利用一个辅助栈A. T1. [初始化] 置栈A为空,并置链接变量$P \gets T$. T2. [$P=\bigwedge$?] 如果$P=\bigwedge$,转到步骤T4. T3. [$栈 \Leftarrow P$] (现在P指向要加以遍历的一个非空二叉树.)置 $A \Leftarrow P$:即是,把P的值放入栈A.然后置$P \to LLINK(P)$并返回步骤T2. T4.

数据结构(C实现)------- 遍历二叉树

本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 二叉树是另一中树型结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒. 根据二叉树的的递归定义可知,二叉树是由3个基本单元组成,根结点.左子树和右子树,因此,若能依次遍历这三部分,便是遍历了整个二叉树.假如以L.D.R分别表示遍历左子树.访问根结点和遍历右子树,则可能有DLR.LDR.LRD.DRL.RD

非递归的方法遍历二叉树

//非递归遍历一棵树 需要借助栈 #include<stdio.h> #include<stdlib.h> struct Tree { int nValue; Tree *pLeft; Tree *pRight; }; struct Stack { Tree *root; Stack *pNext; }; Stack *pStack = NULL; void push(Tree *root) { Stack *temp = (Stack*)malloc(sizeof(Stack))

数据结构算法C语言实现(二十)--- 6.3.1遍历二叉树

一.简述 二叉树的遍历主要是先序.中序.后序及对应的递归和非递归算法,共3x2=6种,其中后序非递归在实现上稍复杂一些.二叉树的遍历是理解和学习递归及体会栈的工作原理的绝佳工具! 此外,非递归所用的栈及相关操作是第三章实现的,但数据类型做了更改. 二.头文件 1 //3_1.h 2 /** 3 author:zhaoyu 4 email:[email protected] 5 date:2016-6-7 6 note:realize my textbook <<数据结构(C语言版)>&g

史上最简明易懂非递归遍历二叉树算法

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 遍历二叉树的递归函数是体现了算法之美的高妙算法,思路清晰,代码简洁,读之赏心悦目.代码例如以下: 程序代码: void PreOrderTraverse_R(BiTree BT)//採用递归方式先序遍历二叉树BT { if(BT != NULL) { printf("%c", BT->data);//输出该结点(根结点) PreOrderTraverse_R(BT->lchi

SDUT 3341 数据结构实验之二叉树二:遍历二叉树

数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点).请建立二叉树并按中序和后序的方式遍历该二叉树. Input 连续输入多组数据,每组数据输入一个长度小于50个字符的字符串. Output 每组输入数据对应输出2行:第1行输出中序遍历序列:第2行输出后序遍历序列