本文章只是自己总结的遍历思路,按照技巧,就可以无脑写出遍历顺序。
DFS对应前中后序遍历,BFS对应层序遍历。
本文章代码用C#实现,以下图的二叉树为例。
一、前序遍历
public static void PreOrder(TreeNode node)
{
if (node == null) return;
Console.Write(node.value + " ");
if (node.left != null) PreOrder(node.left);
if (node.right != null) PreOrder(node.right);
}
技巧:根左右重复,且只打印为根的元素
详细步骤:
新建口诀:根左右,根:A(标黄的元素就打印出来)
左:有左子树(下图红框内),新建口诀:根左右,根:B.
左:无左子树,右:有右子树(下图红框内),新建口诀:根左右,根:C.
左:有左子树(下图红框内),新建口诀:根左右,根:D.
左:无左子树,右:无右子树
回到C(只执行了根和左),右:无右子树,该口诀完毕。
回到B(执行完了根、左和右),该口诀完毕。
回到A(只执行了根和左),右:有右子树(下图红框内),新建口诀:根左右,根:E.
左:无左子树,右:有右子树(下图红框内),新建口诀:根左右,根:F.
左:有左子树(下图红框内),新建口诀:根左右,根:G.
左:有左子树(下图红框内),新建口诀:根左右,根:H.
左:无左子树,右:无右子树
回到G(只执行了根和左),右:有右子树(下图红框内),新建口诀:根左右,根:I.
左:无左子树,右:无右子树
回到G(执行完了根、左和右),该口诀完毕。
回到F(只执行了根和左), 右:无右子树,该口诀完毕。
回到E(执行完了根、左和右), 该口诀完毕。
回到A(执行完了根、左和右), 该口诀完毕。
总顺序(标黄字符):A B C D E F G H I
二、中序遍历
public static void InOrder(TreeNode node)
{
if (node == null) return;
if (node.left != null) InOrder(node.left);
Console.Write(node.value + " ");
if (node.right != null) InOrder(node.right);
}
技巧:左根右重复,且只打印为根的元素
口诀:左根右,左:有左子树(下图红框内),新建口诀:左根右
左:无左子树,根:B,右:有右子树(下图红框内),新建口诀:左根右
左:有左子树(下图红框内),新建口诀:左根右
左:无左子树,根:D,右:无右子树,该口诀完毕。
回到C(只执行了左),根:C,右:无右子树,该口诀完毕。
回到B(执行完了左、根和右),该口诀完毕。
回到A(只执行了左),根:A,右:有右子树(下图红框内),新建口诀:左根右
左:无左子树,根:E,右:有右子树(下图红框内),新建口诀:左根右
左:有左子树(下图红框内),新建口诀:左根右
左:有左子树(下图红框内),新建口诀:左根右
左:无左子树,根:H,右:无右子树,该口诀完毕。
回到G(只执行了左),根:G,右:有右子树(下图红框内),新建口诀:左根右
左:无左子树,根:I,右:无右子树,该口诀完毕。
回到G(执行完了左、根和右),该口诀完毕。
回到F(只执行了左),根:F,右:无右子树,该口诀完毕。
回到E(执行完了左、根和右),该口诀完毕。
回到A(执行完了左、根和右),该口诀完毕。
总顺序(标黄字符):B D C A E H G I F
三、后序遍历
public static void PostOrder(TreeNode node)
{
if (node == null) return;
if (node.left != null) PostOrder(node.left);
if (node.right != null) PostOrder(node.right);
Console.Write(node.value + " ");
}
技巧:左右根重复,且只打印为根的元素
口诀:左右根,左:有左子树(下图红框内),新建口诀:左右根
左:无左子树,右:有右子树(下图红框内),新建口诀:左右根
左:有左子树(下图红框内),新建口诀:左右根
左:无左子树,右:无右子树,根:D,该口诀完毕。
回到C(只执行了左),右:无右子树,根:C,该口诀完毕。
回到B(只执行了左和右),根:B,该口诀完毕。
回到A(只执行了左),右:有右子树(下图红框内),新建口诀:左右根
左:无左子树,右:有右子树(下图红框内),新建口诀:左右根
左:有左子树(下图红框内),新建口诀:左右根
左:有左子树(下图红框内),新建口诀:左右根
左:无左子树,右:无右子树,根:H,该口诀完毕。
回到G(只执行了左),右:有右子树(下图红框内),新建口诀:左右根
左:无左子树,右:无右子树,根:I,该口诀完毕。
回到G(只执行了左和右),根:G,该口诀完毕。
回到F(只执行了左),右:无右子树,根:F,该口诀完毕。
回到E(只执行了左和右),根:E,该口诀完毕。
回到A(只执行了左和右),根:A,该口诀完毕。
总顺序(标黄字符):D C B H I G F E A
四、层序遍历
public static List<char> Level(TreeNode Tree)
{
List<char> res = new List<char>();
Queue<TreeNode> q = new Queue<TreeNode>();
if (Tree != null)
q.Enqueue(Tree); //根节点进队列
while (q.Count > 0) //队列不为空
{
TreeNode node = q.Peek();
res.Add(node.value);
if (node.left != null) //如果有左孩子,入队
q.Enqueue(node.left);
if (node.right != null) //如果有右孩子,入队
q.Enqueue(node.right);
q.Dequeue(); //已经遍历过的节点出队列
}
return res;
}
总顺序(标黄字符):A B E C F D G H I
五、二叉树的性质
参考:二叉树的5个性质