二叉树的三种遍历的应用(表达式,求深度,叶子数,结点数,二叉树的建立,复制)

表达式的表示

如图所示的二叉树表达式: a+b*(c-d)-e/f

若先序遍历此二叉树,按访问结点的先后次序将结点排列起来,其先序序列为: (波兰式,前缀表达式)  -+a*b-cd/ef

按中序遍历,其中序序列为:a+b*c-d-e/f (中缀表达式)

按后序遍历,其后序序列为:abcd-*+ef/- (逆波兰式,后缀表达式)

注:人喜欢中缀形式的算术表达式,对于计算机,使用后缀易于求值

查询二叉树中某个结点

使用先序遍历算法进行查询遍历

// 若二叉树中存在和 x 相同的元素,则 p 指向该结点并返回 OK,否则返回 FALSE
bool Preorder (BiTree T, int x, BiNode *p)
{
    //如果二叉树不为空,开始查询结点
    if (T)
    {
        //如果根节点就是目标结点
        if (T->data == x)
        {
            //p 指向该结点并返回真
            p = T;

            return true;
        }
        else
        {
            //递归调用,也就是先序遍历
            if (Preorder(T->lchild, x, p))
            {
               return true;
            }
            else
            {
                return(Preorder(T->rchild, x, p)) ;
            }
        }//end of else
    }//end of if
    else
    {
        return false;
    }
}

统计二叉树中叶子结点的个数

还是先序遍历的过程

//统计二叉树中所有末位结点的个数,也就是叶子结点的个数的统计
void CountLeaf(BiTree T, int *count)
{
    //如果不为空树
    if (T != NULL)
    {
        //如果树的左右子树都为空,那么叶子结点数+1
        if ((!T->lchild) && (!T->rchild))
        {
            // 对叶子结点计数
            count++;
        }
        //否则,继续递归遍历
        CountLeaf(T->lchild, count);
        CountLeaf(T->rchild, count);
    } // if
}

统计二叉树中所有结点的个数

//返回指针T所指二叉树中所有结点个数
//还是前序遍历
int Count(BiTree T)
{
    //如果 T 为空
    if (!T)
    {
        //则说明是空树,返回0个结点
        return 0;
    }
    //如果 T 的左右子树 为空,说明只有一个结点,根节点而已
    if (!T->lchild && !T->rchild)
    {
       return 1;
    }
    else{
        //否则,递归遍历
        int m = Count(T->lchild);
        int n = Count(T->rchild);

        return (m + n + 1);
    } //else
}

求二叉树的深度(后序遍历)

//求二叉树的深度,后续遍历的使用
int Depth(BiTree T)
{
    int depth;
    int depthLeft;
    int depthRight;
    //如果二叉树为空
    if (!T)
    {
        depth = 0;
    }
    else
    {
        depthLeft = Depth(T->lchild);
        depthRight = Depth(T->rchild);
        depth = 1 + (depthLeft > depthRight ? depthLeft : depthRight);
    }

    return depth;
}

复制二叉树(也是后序遍历),其基本操作为:生成一个结点。

//生成一个二叉树的结点,(其数据域为item,左指针域为lptr,右指针域为rptr)
BiNode * GetTreeNode(int item, BiNode *lptr, BiNode *rptr)
{
    BiTree T;
    //如果新建结点失败
    if (!(T = new BiNode))
    {
        //退出
        exit(1);
    }
    //新建结点成功
    T->data = item;
    //
    T->lchild = lptr;
    T->rchild = rptr;
    //返回新建的结点的指针
    return T;
}

BiNode * CopyTree(BiNode *T)
{
    BiNode *newT;
    BiNode *newlptr;
    BiNode *newrptr;
    //如果源树为空
    if (!T)
    {
        //返回空
       return NULL;
    }
    //如果根的左子树不为空
    if (T->lchild)
    {
        newlptr = CopyTree(T->lchild); //复制左子树
    }
    else
    {
        //左子树为 null
        newlptr = NULL;
    }
    //如果根的右子树不为空
    if (T->rchild)
    {
        newrptr = CopyTree(T->rchild); //复制右子树
    }
    else
    {
        //否则,右子树为 null
        newrptr = NULL;
    }
    //新生成一个二叉树的结点,也就是后续遍历的过程
    newT = GetTreeNode(T->data, newlptr, newrptr);

    return newT;
}

建立二叉树的存储结构,以递归方式建立二叉树。

输入结点值的顺序必须对应二叉树结点先序遍历的顺序。并约定以输入序列中不可能出现的值作为空结点的值以结束递归。例如用“@”或用“-1”表示字符序列或正整数序列空结点。

如图所示的二叉树的先序遍历顺序为

A B C @ @ D E @ G @ @ F @ @ @

//递归建立二叉树
bool CreateBiTree(BiTree T)
{
    char ch;
    //输入结点的值
    scanf(&ch);
    //如果输入空字符
    if(ch == ' ')
    {
        //代表空结点
        T = NULL;
    }
    else
    {
        T = (BiNode*)malloc(sizeof(BiNode));
        //如果新建结点失败
        if (!T)
        {
             exit(1);
        }
        //成功。先序遍历的顺序建立二叉树
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }

    return true;
}

 

辛苦的劳动,转载请注明出处,谢谢……

http://www.cnblogs.com/kubixuesheng/p/4388534.html

时间: 2024-11-22 19:58:04

二叉树的三种遍历的应用(表达式,求深度,叶子数,结点数,二叉树的建立,复制)的相关文章

java中关于Map的三种遍历方法详解_java

map的三种遍历方法!集合的一个很重要的操作---遍历,学习了三种遍历方法,三种方法各有优缺点~~ 复制代码 代码如下: /* * To change this template, choose Tools | Templates * and open the template in the editor. */package cn.tsp2c.liubao;import java.util.Collection;import java.util.HashMap;import java.util

二叉树的存储方式以及递归和非递归的三种遍历方式

树的定义和基本术语 树(Tree)是n(n>=0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:   (1)有且仅有一个特定的称为根(Root)的结点:   (2)其余的结点可分为m(m>=0)个互不相交的子集T1,T2,T3-Tm,其中每个子集又是一棵树,并称其为子树(Subtree). 树形结构应用实例: 1.日常生活:家族谱.行政组织结构:书的目录 2.计算机:资源管理器的文件夹:     编译程序:用树表示源程序的语法结构:     数据库系统:用树组织信息:     分

Java list三种遍历方法性能比较

从c/c++语言转向java开发,学习java语言list遍历的三种方法,顺便测试各种遍历方法的性能,测试方法为在ArrayList中插入1千万条记录,然后遍历ArrayList,发现了一个奇怪的现象,测试代码例如以下: package com.hisense.tiger.list; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListTest { publi

c++二叉树的几种遍历算法_C 语言

1. 前序/中序/后序遍历(递归实现) 复制代码 代码如下: // 前序遍历void BT_PreOrder(BiTreePtr pNode){ if (!pNode)  return;    visit(pNode);   BT_PreOrder(pNode->left); BT_PreOrder(pNode->right);   }// 中序遍历void BT_PreOrder(BiTreePtr pNode){  if (!pNode)  return;     BT_PreOrder(

PHP遍历数组的三种方法及效率对比分析_php技巧

本文实例分析了PHP遍历数组的三种方法及效率对比.分享给大家供大家参考.具体分析如下: 今天有个朋友问我一个问题php遍历数组的方法,告诉她了几个.顺便写个文章总结下,如果总结不全还请朋友们指出 第一.foreach() foreach()是一个用来遍历数组中数据的最简单有效的方法. <?php $urls= array('aaa','bbb','ccc','ddd'); foreach ($urls as $url){ echo "This Site url is $url! <b

PHP遍历数组的三种方法及效率对比分析

 这篇文章主要介绍了PHP遍历数组的三种方法及效率对比,实例分析了foreach.while与for三种遍历数组的方法与相关的效率比对,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例分析了PHP遍历数组的三种方法及效率对比.分享给大家供大家参考.具体分析如下: 今天有个朋友问我一个问题php遍历数组的方法,告诉她了几个.顺便写个文章总结下,如果总结不全还请朋友们指出 第一.foreach() foreach()是一个用来遍历数组中数据的最简单有效的方法. ? 1 2 3 4 5 6

深入理解二叉树的非递归遍历_C 语言

二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁.而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现.在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对来说要难一点.一.前序遍历前序遍历按照"根结点-左孩子-右孩子"的顺序进行访问.1.递归实现 复制代码 代码如下: void preO

spring配置datasource三种方式

spring配置datasource三种方式 1.使用org.springframework.jdbc.datasource.DriverManagerDataSource 说明:DriverManagerDataSource建立连接是只要有连接就新建一个connection,根本没有连接池的作用. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSour

jquery 动态加载js三种方法

<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-