这一节是关于二叉树的遍历的,常用的有四种遍历二叉树,分别为先序,中序,后序,层次遍历二叉树。利用我们上一节生成的二叉树举例,递归是我们比较常用的方法,看起来比较易懂,代码也比较优美。非递归算法则用另外一种方式对其进行实现。
递归算法:
先序遍历:根,左,右
static void PreOrder<T>(BinaryTreeNode<T> root)
{
if (root != null)
{
Console.WriteLine(root.Value);
PreOrder<T>(root.Left);
PreOrder<T>(root.Right);
}
}中序遍历:左,根,右
static void MidOrder<T>(BinaryTreeNode<T> root)
{
if (root != null)
{
MidOrder<T>(root.Left);
Console.WriteLine(root.Value);
MidOrder<T>(root.Right);
}
}后序遍历:左,右,根
static void BackOrder<T>(BinaryTreeNode<T> root)
{
if (root != null)
{
BackOrder<T>(root.Left);
BackOrder<T>(root.Right);
Console.WriteLine(root.Value);
}
}
层序遍历:会从根结点开始,从左到右,从上到下遍历每个结点,需要用到队列,会在非递归遍历中给出。
非递归算法:
先序遍历
static void PreOrderWithStack<T>(BinaryTreeNode<T> root)
{
Stack<BinaryTreeNode<T>> stack = new Stack<BinaryTreeNode<T>>();
BinaryTreeNode<T> node;
node = root;
while (node != null || stack.Count > 0)
{
//遍历左子树
while (node != null)
{
Console.WriteLine(node.Value);
stack.Push(node);
node = node.Left;
}
//遍历右子树
if (stack.Count > 0)
{
node = stack.Pop();
node = node.Right;
}
}
}中序遍历,
static void MidOrderWithStack<T>(BinaryTreeNode<T> root)
{
Stack<BinaryTreeNode<T>> stack = new Stack<BinaryTreeNode<T>>();
BinaryTreeNode<T> node;
node = root;
while (node != null || stack.Count > 0)
{
//遍历左子树
while (node != null)
{
stack.Push(node);
node = node.Left;
}
//遍历右子树
if (stack.Count > 0)
{
node = stack.Pop();
Console.WriteLine(node.Value);
node = node.Right;
}
}
}后序遍历,构造了一个结构体,并加入了L,R作为标记位,首先遍历左子树,将标记位都置为L。然后将栈顶的标记赋为R,这个时候并不将其输出,继续遍历他的右子树,如果没有右子树则输出值,继续遍历右子树。
public enum Side { L, R };
public struct StackNode<T>
{
public BinaryTreeNode<T> node;
public Side side;
}
static void BackOrderWithStack<T>(BinaryTreeNode<T> root)
{
Stack<StackNode<T>> stack = new Stack<StackNode<T>>();
StackNode<T> stackNode= new StackNode<T>();
BinaryTreeNode<T> node;
node = root;
while (node != null || stack.Count > 0)
{
//遍历左子树
while (node != null)
{
stackNode.node = node;
stackNode.side = Side.L;
stack.Push(stackNode);
node = node.Left;
}
while (stack.Count > 0 && stack.Peek().side == Side.R)
{
stackNode = stack.Pop();
node = stackNode.node;
Console.WriteLine(node.Value);
}
if (stack.Count > 0)
{
stackNode = stack.Pop();
stackNode.side = Side.R;
stack.Push(stackNode);
node = stack.Peek().node.Right;
}
else
{
break;
}
}
}层序遍历:
static void LayerOrder<T>(BinaryTreeNode<T> root)
{
Queue<BinaryTreeNode<T>> queue = new Queue<BinaryTreeNode<T>>();
Console.WriteLine(root.Value);
BinaryTreeNode<T> node;
if (root.Left != null)
{
queue.Enqueue(root.Left);
}
if (root.Right != null)
{
queue.Enqueue(root.Right);
}
while (queue.Count > 0)
{
node=queue.Dequeue();
Console.WriteLine(node.Value);
if (node.Left !=null)
{
queue.Enqueue(node.Left);
}
if (node.Right != null)
{
queue.Enqueue(node.Right);
}
}
queue.Clear();
}二叉树的排序方法还远远不止这些,本文中给出这些算法也只是给了一个开头,对于树算法的研究远远没有尽头。

浙公网安备 33010602011771号