美文网首页
【数据结构】【C#】028-二叉树(BT):🌱遍历的应用(输出叶

【数据结构】【C#】028-二叉树(BT):🌱遍历的应用(输出叶

作者: lijianfex | 来源:发表于2018-11-13 07:19 被阅读13次
public class BinTree<T>
{
    private static string output;

    private static void VisitNode(TreeNode<T> node)
    {
        output += node.Data.ToString() + " ";
    }

    public static void DisPlayOutPut()//显示遍历结果
    {
        Debug.Log(output);
        output = string.Empty;
    }

一、输出树的叶子节点

1、非递归:

在利用先序遍历(非递归)方法,访问节点之前,判断是否该节点左右孩子都空

if ( node.Left == null && node.Right == null )

    /// <summary>
    /// 输出树的叶子结点:非递归---利用先序非递归实现
    /// </summary>
    /// <param name="rootNode"></param>
    public static void PreOderPrintLeaves(TreeNode<T> rootNode)
    {
        TreeNode<T> node = rootNode;

        LinkStack<TreeNode<T>> S = new LinkStack<TreeNode<T>>();//使用了自己定义的链栈
        
        while (node != null || !S.IsEmpty())
        {
            while (node != null)
            {
                if (node.Left == null && node.Right == null)//判断是否是叶节点
                {
                    VisitNode(node); //访问该节点
                }
                S.Push(node);
                node = node.Left;
            }
            if (!S.IsEmpty())
            {
                node = S.Pop();
                node = node.Right;
            }
        }
        
    }

2、递归式:

与先序递归遍历类似,同样的加一个判断即可:if ( BT.Left == null && BT.Right == null )
     /// <summary>
    /// 输出树的叶子结点:递归式
    /// </summary>
    /// <param name="rootNode"></param>
    public static void PrintLeaves(TreeNode<T> rootNode)
    {
        TreeNode<T> BT = rootNode;
        if (BT != null)
        {
            if (BT.Left == null && BT.Right == null)
            {
                VisitNode(BT); //访问该节点
            }
            PrintLeaves(BT.Left);
            PrintLeaves(BT.Right);
        }
    
    }

二、输出树的高度

1、非递归:

利用层次遍历的非递归,增加 deepth变量,记录下遍历的层次,最后的层次即树的高度
    /// <summary>
    /// 输出树的高度:非递归---利用层序非递归实现
    /// </summary>
    /// <param name="rootNode"></param>
    /// <returns></returns>
    public static int LayerOderBinTreeHigh(TreeNode<T> rootNode)
    {
        if (rootNode == null) return 0;

        int deepth = 0; //记录遍历层次

        LinkQueue<TreeNode<T>> queue= new LinkQueue<TreeNode<T>>();   //创建队列,使用自定义的链队列

        TreeNode<T> outNode;      

        queue.Enqueue(rootNode);


        while (!queue.IsEmpty())
        {
            ++deepth;//当前遍历的层次

            int levelNodesCount = queue.Count;

            for (int i = 0; i < levelNodesCount; ++i)
            {
                outNode = queue.Dequeue();

                if (outNode.Left != null) queue.Enqueue(outNode.Left);
                if (outNode.Right != null) queue.Enqueue(outNode.Right);
            }

        }

        return deepth; //最终的层次:树的高度
    }

2、递归式:

利用公式 max(LH,RH)+1: 即左右子树的最大的加1 为树高度

    /// <summary>
    /// 输出树的高度:递归式---利用公式:max(LH,RH)+1
    /// </summary>
    /// <param name="rootNode"></param>
    /// <returns></returns>
    public static int BinTreeHigh(TreeNode<T> rootNode)
    {
        int LH, RH;
        TreeNode<T> BT = rootNode;
        if (BT == null)
        {
            return 0;
        }
        else
        {
            LH = BinTreeHigh(BT.Left);
            RH = BinTreeHigh(BT.Right);
            return LH > RH ? LH + 1 : RH + 1;
        }
    }

三、输出某层的所有节点(也可以输出多个层的)

1、非递归:

利用层序遍历的非递归,在访问时,判断是否 deepth==level
(输出多层,即 minLevel<=deepth<=maxLevel)
/// <summary>
    /// 输出某层的所有节点(层序遍历:非递归)
    /// </summary>
    /// <param name="rootNode"></param>
    /// <param name="level"></param>
    public static void LayerOderPrintLevelNodes(TreeNode<T> rootNode, int level)
    {
       if (rootNode == null) return;

        int deepth = 0;//记录遍历层次

        LinkQueue<TreeNode<T>> queue = new LinkQueue<TreeNode<T>>();   //创建队列,使用自定义的链队列

        TreeNode<T> outNode;

        queue.Enqueue(rootNode);

        while (!queue.IsEmpty())
        {
            ++deepth;

            int levelNodesCount = queue.Count;

            for (int i = 0; i < levelNodesCount; ++i)
            {
                outNode = queue.Dequeue();

                if (deepth == level) //判断是否是要访问的层的节点
                {
                    VisitNode(outNode);//访问节点
                }

                if (outNode.Left != null) queue.Enqueue(outNode.Left);
                if (outNode.Right != null) queue.Enqueue(outNode.Right);
            }

        }
        
    }

2、递归式:

通过判断 level==1,来确定是否到达要访问的层的节点
/// <summary>
    /// 输出某层的所有节点(递归式)
    /// </summary>
    /// <param name="rootNode"></param>
    /// <param name="level"></param>
    public static void PrintLevelNodes(TreeNode<T> rootNode, int level)
    {
        if (rootNode == null) return;
        TreeNode<T> BT = rootNode;
        if (level == 1)
        {
            VisitNode(BT);
        }
        else
        {
            PrintLevelNodes(BT.Left, level - 1);
            PrintLevelNodes(BT.Right, level - 1);
        }
    }

测试用例:

public class _017_BinTree : MonoBehaviour
{
    //二叉树结构: 
    private string tree = @"     
              1
             / \
            2   3
           / \
          4   5
         / \ 
        6   7              
                           ";

    TreeNode<int> root; //二叉树根节点

    //创建二叉树
    void CreatBinTree()
    {
       
        root = new TreeNode<int>(1);
        TreeNode<int> t2 = new TreeNode<int>(2);
        TreeNode<int> t3 = new TreeNode<int>(3);
        TreeNode<int> t4 = new TreeNode<int>(4);
        TreeNode<int> t5 = new TreeNode<int>(5);
        TreeNode<int> t6 = new TreeNode<int>(6);
        TreeNode<int> t7 = new TreeNode<int>(7);

        root.SetLRChild(t2, t3);
        t2.SetLRChild(t4, t5);
        t4.SetLRChild(t6, t7);
    }

    void Start()
    {
        CreatBinTree();//创建二叉树

        
        Debug.Log("二叉树结构:" + "\n" + tree);

       
        //遍历应用:
        Debug.Log("输出树的叶子节点:");
        Debug.Log("---------非递归----利用先序非递归实现-----");
        BinTree<int>.PreOderPrintLeaves(root);
        BinTree<int>.DisPlayOutPut();

        Debug.Log("---------递归式----利用先序递归实现-------");
        BinTree<int>.PrintLeaves(root);
        BinTree<int>.DisPlayOutPut();

        Debug.Log("输出树的高度:");
        Debug.Log("---------非递归----利用层序非递归实现------");
        int high1= BinTree<int>.LayerOderBinTreeHigh(root);
        Debug.Log("树的高度: " + high1);        

        Debug.Log("---------递归式----利用公式:max(LH,RH)+1 ");
        int high2 = BinTree<int>.BinTreeHigh(root);
        Debug.Log("树的高度: " + high2);

        Debug.Log("输出第4层的所有节点:");
        Debug.Log("---------非递归----判断 deepth==level-----");
        BinTree<int>.LayerOderPrintLevelNodes(root,4);
        BinTree<int>.DisPlayOutPut();

        Debug.Log("---------递归式----判断 Leve==1-----------");
        BinTree<int>.PrintLevelNodes(root, 4);
        BinTree<int>.DisPlayOutPut();

    }
}

测试结果:


其他应用:

四、 二元运算表达式树及其遍历

1、先序遍历得到前缀表达式:+ + a * b c * + * d e f g
2、中序遍历得到中缀表达式:a + b * c +d * e + f * g(中缀表达式会受到运算符优先级的影响 :需要在遍历时加括号
3、后序遍历得到后缀表达式:a b c * + d e * f + g * +

五、两种遍历序列确定二叉树

已知三种遍历中的任意两种遍历序列, 能否唯一确定一棵二叉树呢?

答案:必须要有中序遍历才行

例子:先序和中序遍历序列来确定一棵二叉树
  • 根据先序遍历序列第一个结点确定根结点
  • 根据根结点中序遍历序列中分割出左右两个子序列
  • 左子树和右子树分别递归使用相同的方法继续分解

相关文章

  • 【数据结构】【C#】028-二叉树(BT):🌱遍历的应用(输出叶

    一、输出树的叶子节点 1、非递归: 在利用先序遍历(非递归)方法,访问节点之前,判断是否该节点左右孩子都空if (...

  • C# 实现二叉树的遍历算法

    C# 实现二叉树的遍历算法 数据结构 BiTreeNode: 树节点public char Value { get...

  • 二叉树的遍历

    数据结构算法 二叉树的遍历

  • 2019-03-08 lintcode2

    二叉树路径遍历 输出所有根节点到叶子节点的路径找出所有路径中相加总和等于给定值的路径 数据结构 链表:遍历、增加、...

  • python实现二叉树的遍历

    二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有深度遍历和广度遍历,...

  • 算法系列--二叉树的三种遍历的六种实现

    0. 二叉树是常见的数据结构,二叉树常见的遍历方式有前序遍历,中序遍历和后序遍历。前序遍历就是中-左-右节点的顺序...

  • 经典算法代码集

    本文是经典算法的集合,使用C#语言来实现。 1. 二叉树 二叉树结构定义 1.1 二叉树的遍历 先定义一个遍历处理...

  • 二叉树的四种遍历方法

    二叉树的数据结构 1、前序遍历(递归) 2、中序遍历(递归) 3、后序遍历(递归) 4、层次遍历(队列)

  • Python实现深度优先与广度优先

    二叉树的两种遍历是数据结构的经典考察题目, 广度遍历考察队列结构, 深度遍历考察递归 二叉树 深度优先 先序遍历(...

  • 常见数据结构-Java

    一、链表 二、二叉树 前序遍历-先输出当前结点的数据,再依次遍历输出左结点和右结点 中序遍历-先遍历输出左结点,再...

网友评论

      本文标题:【数据结构】【C#】028-二叉树(BT):🌱遍历的应用(输出叶

      本文链接:https://www.haomeiwen.com/subject/hvucfqtx.html