二叉树遍历在Unity中的实现

前言:今天放一天,想到要放国庆假了就心烦气躁,躺床上又焦虑,回想起面试官的一副扑克脸,马上跳起来看了看数据结构。

今天复习了二叉树,包括一些基本概念和特性,当看到二叉树遍历的章节时,马上联想到了Unity的Hierachy面板中的游戏物体关系,就在Unity中仿造了一波”二叉树“;

准备工作:

先写一个二叉树类,成员包括自身名称value,左子树,右子树

public class BinaryTree
{
    public string value;
    public BinaryTree Left;
    public BinaryTree Right;

    public BinaryTree(Transform root)
    {
        value = root.name;
        if (root.childCount==0)
        {
            return;
        }
        else if (root.childCount==1)
        {
            if (root.GetChild(0) != null)
            {
                Left = new BinaryTree(root.GetChild(0));
            }
            else
            {
                Left = null;
            }
        }
        else if (root.childCount==2)
        {
            if (root.GetChild(0) != null)
            {
                Left = new BinaryTree(root.GetChild(0));
            }
            else
            {
                Left = null;
            }

            if (root.GetChild(1) != null)
            {
                Right = new BinaryTree(root.GetChild(1));
            }
            else
            {
                Right = null;
            }
        }
    }
}

在Unity中添加若干子物体

 

 

因为Unity中,游戏物体的关系并非是《二叉树》,而是《树》,所以在代码中我特意添加判断子物体数,而且在Unity中不会出现左子树不存在,右子树存在的情况。

一、先序遍历

1.递归方式:

void NodeFirst(BinaryTree t)
    {
        if (t!=null)
        {
            Debug.Log(t.value);
            NodeFirst(t.Left);
            NodeFirst(t.Right);
        }
    }

2.非递归方式:

void TravalFirst(BinaryTree input)
    {
        BinaryTree T = input;
        Stack<BinaryTree> s = new Stack<BinaryTree>();
        while (T!=null||s.Count>0)
        {
            while (T!=null)
            {
                Debug.Log(T.value);
                s.Push(T);
                T = T.Left;
            }
            T = s.Pop();
            T = T.Right;
        }
    }

3.输出:

 

 

二、中序

1.递归

void NodeMid(BinaryTree t)
    {
        if (t != null)
        {
            NodeMid(t.Left);
            Debug.Log(t.value);
            NodeMid(t.Right);
        }
    }

2.非递归

void TravalMid(BinaryTree input)
    {
        BinaryTree T = input;
        Stack<BinaryTree> s = new Stack<BinaryTree>();
        while (T!=null|| s.Count>0)
        {
            while (T!=null)
            {
                s.Push(T);
                T = T.Left;
            }
            T = s.Pop();
            Debug.Log(T.value);
            T = T.Right;
        }
    }

3.输出

 

 

三、后序

1.递归

void NodeLast(BinaryTree t)
    {
        if (t != null)
        {
            NodeLast(t.Left);
            NodeLast(t.Right);
            Debug.Log(t.value);
        }
    }

2.非递归

void TravalLast(BinaryTree input)
    {
        BinaryTree T = input;
        Stack<BinaryTree> s = new Stack<BinaryTree>();
        BinaryTree visited = null;
        while (T!=null||s.Count>0)
        {
            if (T!=null)
            {
                s.Push(T);
                T = T.Left;
            }
            else
            {
                T = s.Peek();
                if (T.Right!=null&&visited!=T.Right)
                {
                    T = T.Right;
                    s.Push(T);
                    T = T.Left;
                }
                else
                {
                    T = s.Pop();
                    Debug.Log(T.value);
                    visited = T;
                    T = null;
                }
            }
        }
    }

这里单独解释一下,因为我做这个实在是想不出了,看了看网上的,其实我也是云里雾里的。这里不能像前两个一样,早早的把父节点弹出栈,需要先输出判断左右子树后,再弹出父节点。

3.输出

 

 

其实我更愿意用递归,因为非递归的可读性有点差。考虑到可执行性的原因,所以我又学习了一遍非递归的方式,主要还是使用栈的特性。加油,菜鸟也有鲲鹏之志

posted @ 2021-09-25 21:51  军酱不是酱  阅读(368)  评论(0编辑  收藏  举报