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

表达式的表示

如图所示的二叉树表达式: 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;
}
时间: 2024-10-12 02:27:08

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

二叉树的三种遍历方式的循环和递归的实现方式

///////////////////头文件:BST.h//////////////////////// #ifndef BST_H #define BST_H #include "StdAfx.h" #include<iostream> #include<stack> template<typename DataType> class BST { public: class Node { public: Node(int data=0):m_dat

二叉树的三种遍历简单版

同学突然向我问二叉树的三种遍历代码.数据结构刚刚学了,自己很吃力的敲了出来. 和老师演示的代码有很大差距. #include <stdio.h>#include <string.h>#include <stdlib.h> #define Error -1#define Right 1 struct BiTnode{    char data;    struct BiTnode *LChild;    struct BiTnode *RChild; }; BiTnode

公交车站捡垃圾之二叉树的三种遍历方法

# 二叉树的遍历 今天下午看了二叉树的三种遍历方式,虽然能写出代码,但是理解可能不太到位,感觉很容易忘,所以想到一个形象的方法,把每个节点当作公交车站,而访问节点则是在这个公交车站捡垃圾,右子树和左子树则表示岔路.然后这个捡垃圾的人钟爱左边这个方向,所以一直以左优先.甲乙丙三个人,都爱捡垃圾,但是思考方式不同,所以捡垃圾的方法有点不同. 先序遍历 先序遍历最简单,秉承的原则是,甲很小心谨慎,每次经过公交车站,怕别人捡了,都把垃圾先捡到手,直到左边的路走完了,再往回走,但是回来的过程中,在公交车站

PTA 二叉树的三种遍历(先序、中序和后序)

6-5 二叉树的三种遍历(先序.中序和后序) (6 分) 本题要求实现给定的二叉树的三种遍历. 函数接口定义: void Preorder(BiTree T); void Inorder(BiTree T); void Postorder(BiTree T); T是二叉树树根指针,Preorder.Inorder和Postorder分别输出给定二叉树的先序.中序和后序遍历序列,格式为一个空格跟着一个字符. 其中BinTree结构定义如下: typedef char ElemType; typed

POJ2255 TreeRecovery(二叉树的三种遍历)

Description Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital letters in the nodes. This is an example of one of her creations: D / \ B E / \ \ A C G / F To recor

二叉树的三种遍历(非递归)

先定义二叉树: /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ 二叉树的先序遍历(以LeetCode 144.为例): class Solution { public: vector<int> preo

二叉树的三种遍历(前序,中序,后序)

参考<大话数据结构>P178~184——二叉树的遍历. 用书上的这个二叉树: 代码和解释如下(VS2012测试通过): 1 #include <iostream> 2 using namespace std; 3 4 //二叉树的二叉链表结点结构定义 5 typedef struct BiTNode 6 { 7 char data; 8 struct BiTNode *lchild,*rchild; 9 }BiTNode; 10 11 //输入前序遍历,创建二叉树 12 //这里输

折半查找/二分查找 以及二叉树的 三种遍历方式

二分查找   线性查找 1.二分查找 public class BinarySearch { /** * 二分查找 * @param data * @return */ public int binarySearch(long[] data,long n) { //左右 端点 int left =0; int right =data.length-1; //中间元素 int mid=-1; while(left<right){ // 有两种情况 1.left = right 2. left>r

二叉树的三种遍历

 1.先序遍历:先序遍历是先输出根节点,再输出左子树,最后输出右子树.上图的先序遍历结果就是:ABCDEF 2.中序遍历:中序遍历是先输出左子树,再输出根节点,最后输出右子树.上图的中序遍历结果就是:CBDAEF 3.后序遍历:后序遍历是先输出左子树,再输出右子树,最后输出根节点.上图的后序遍历结果就是:CDBFEA #include <stdio.h> #include <stdlib.h> typedef char TelemType; typedef struct TNo