先总结一下
二叉树的遍历方式有四种
深度优先遍历有三种:这三种的循环遍历方法中都用到了栈stack。不建议采用递归的原因在于如果太深,会有可能导致栈溢出
前序遍历 (根左右)
中序遍历(左根右)
后序遍历(左右根)
广度优先
层序遍历(从上到下,从左往右)用到了队列(queue):先进先出
附上源码:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class BinaryTree : MonoBehaviour
{
private TreeNode startNode;
public void AddTree()
{
TreeNode node=new TreeNode(1);
startNode = node;
node.leftChild=new TreeNode(2);
node.leftChild.leftChild=new TreeNode(3);
node.leftChild.leftChild.leftChild=new TreeNode(4);
node.leftChild.leftChild.rightChild = new TreeNode(5);
node.leftChild.rightChild = new TreeNode(6);
node.leftChild.rightChild.leftChild = new TreeNode(7);
node.rightChild = new TreeNode(8);
node.rightChild.leftChild = new TreeNode(9);
node.rightChild.rightChild = new TreeNode(10);
}
public class TreeNode
{
public int value;
public TreeNode leftChild;
public TreeNode rightChild;
public TreeNode(int v)
{
value = v;
}
}
//前序遍历 中左右 递归
public void PreOrder(TreeNode node)
{
if (node != null)
{
Debug.Log(node.value);
PreOrder(node.leftChild);
PreOrder(node.rightChild);
}
}
//前序遍历 中左右 非递归
public void PreOrderLoop(TreeNode _node)
{
Stack<TreeNode> stack=new Stack<TreeNode>();
TreeNode node = _node;
while (node != null||stack.Any())
{
if (node != null)
{
stack.Push(node);
Debug.Log(node.value);
node = node.leftChild;
}
else
{
var temNode = stack.Pop();
node = temNode.rightChild;
}
}
}
//中序遍历 左中右 递归
public void InOrder(TreeNode node)
{
if (node != null)
{
InOrder(node.leftChild);
Debug.Log(node.value);
InOrder(node.rightChild);
}
}
//中序遍历 左中右 非递归
public void InOrderLoop(TreeNode _node)
{
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = _node;
while (node != null || stack.Any())
{
if (node != null)
{
stack.Push(node);
node = node.leftChild;
}
else
{
var temNode = stack.Pop();
Debug.Log(temNode.value);
node = temNode.rightChild;
}
}
}
//中序遍历 左右中 递归
public void PostOrder(TreeNode node)
{
if (node != null)
{
PostOrder(node.leftChild);
PostOrder(node.rightChild);
Debug.Log(node.value);
}
}
//中序遍历 左右中 非递归 存储上一个变量
public void PostOrderLoopPreNode(TreeNode _node)
{
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = _node;
TreeNode pre = null;
stack.Push(node);
while (stack.Any())
{
node = stack.Peek();
if ((node.leftChild == null&&node.rightChild==null)||
(pre!=null&&(pre==node.leftChild||pre==node.rightChild))
)
{
Debug.Log(node.value);
pre = node;
stack.Pop();
}
else
{
if (node.rightChild != null)
{
stack.Push(node.rightChild);
}
if (node.leftChild != null)
{
stack.Push(node.leftChild);
}
}
}
}
//中序遍历 左右中 非递归 把检测过的节点放入哈希表
public void PostOrderLoopHashSet(TreeNode _node)
{
Stack<TreeNode> stack = new Stack<TreeNode>();
HashSet<TreeNode> hash = new HashSet<TreeNode>();
TreeNode node = _node;
while (node!=null||stack.Any())
{
if (node != null)
{
stack.Push(node);
node = node.leftChild;
}
else
{
var temNode = stack.Peek();
if (temNode.rightChild != null && !hash.Contains(temNode.rightChild))
{
node = temNode.rightChild;
hash.Add(node);
}
else
{
Debug.Log(temNode.value);
hash.Add(node);
stack.Pop();
}
}
}
}
public void LevelOrder(TreeNode _node)
{
Queue<TreeNode> queue=new Queue<TreeNode>();
TreeNode node = _node;
queue.Enqueue(node);
while (queue.Any())
{
var temNode= queue.Dequeue();
Debug.Log(temNode.value);
if (temNode.leftChild != null)
{
queue.Enqueue(temNode.leftChild);
}
if (temNode.rightChild != null)
{
queue.Enqueue(temNode.rightChild);
}
}
}
// Start is called before the first frame update
void Start()
{
AddTree();
// PreOrder(startNode);
// PreOrderLoop(startNode);
// InOrder(startNode);
// InOrderLoop(startNode);
// PostOrder(startNode);
// PostOrderLoopPreNode(startNode);
// PostOrderLoopHashSet(startNode);
LevelOrder(startNode);
}
}