前中后序遍历二叉树
public class BinaryTreeNode<T>
{
public T Value { get;set; }
public BinaryTreeNode<T> Parent { get;set; }
public BinaryTreeNode<T> Left { get;set; }
public BinaryTreeNode<T> Right { get;set; }
public virtual void Traverse(TraverseOrder order, NodeWorker<T> worker)
{
if (worker == null) { return; }
var left = this.Left;
var right = this.Right;
switch (order)
{
case TraverseOrder.Preorder:
/* recursive preorder traverse
worker.DoActionOnNode(this);
if (left != null) { Left.Traverse(order, worker); }
if (right != null) { Right.Traverse(order, worker); }
*/
PreorderTraverse(worker);
break;
case TraverseOrder.Inorder:
/* recursive inorder traverse
if (left != null) { Left.Traverse(order, worker); }
worker.DoActionOnNode(this);
if (right != null) { Right.Traverse(order, worker); }
*/
InorderTraverse(worker);
break;
case TraverseOrder.Postorder:
/* recursive postorder traverse
if (left != null) { Left.Traverse(order, worker); }
if (right != null) { Right.Traverse(order, worker); }
worker.DoActionOnNode(this);
*/
PostorderTraverse(worker);
break;
default:
break;
}
}
void PreorderTraverse(NodeWorker<T> worker)
{
var stack = new Stack<BinaryTreeNode<T>>();
stack.Push(this);
while (stack.Count > 0)
{
var node = stack.Pop();
//if (node == null) { continue; }
//else
{
var right = node.Right;
var left = node.Left;
worker.DoActionOnNode(node);
if (right != null) { stack.Push(right); }
if (left != null) { stack.Push(left); }
}
}
}
/* This works fine and is better for tuition. The code above is an optimized version.
void PreorderTraverse(NodeWorker<T> worker)
{
var stack = new Stack<BinaryTreeNode<T>>(); var stackReady4Visit = new Stack<bool>();
stack.Push(this); stackReady4Visit.Push(false);
while (stack.Count > 0)
{
var node = stack.Pop(); var ready4Visit = stackReady4Visit.Pop();
//if (node == null) { continue; }
if (ready4Visit)
{
worker.DoActionOnNode(node);
}
else
{
var right = node.Right;
var left = node.Left;
if (right != null) { stack.Push(right); stackReady4Visit.Push(false); }
if (left != null) { stack.Push(left); stackReady4Visit.Push(false); }
stack.Push(node); stackReady4Visit.Push(true);
}
}
}
*/
void InorderTraverse(NodeWorker<T> worker)
{
var stack = new Stack<BinaryTreeNode<T>>(); var stackReady4Visit = new Stack<bool>();
stack.Push(this); stackReady4Visit.Push(false);
while (stack.Count > 0)
{
var node = stack.Pop(); var ready4Visit = stackReady4Visit.Pop();
//if (node == null) { continue; }
if (ready4Visit)
{
worker.DoActionOnNode(node);
}
else
{
var right = node.Right;
var left = node.Left;
if (right != null) { stack.Push(right); stackReady4Visit.Push(false); }
stack.Push(node); stackReady4Visit.Push(true);
if (left != null) { stack.Push(left); stackReady4Visit.Push(false); }
}
}
}
void PostorderTraverse(NodeWorker<T> worker)
{
var stack = new Stack<BinaryTreeNode<T>>(); var stackReady4Visit = new Stack<bool>();
stack.Push(this); stackReady4Visit.Push(false);
while (stack.Count > 0)
{
var node = stack.Pop(); var ready4Visit = stackReady4Visit.Pop();
//if (node == null) { continue; }
if (ready4Visit)
{
worker.DoActionOnNode(node);
}
else
{
var right = node.Right;
var left = node.Left;
stack.Push(node); stackReady4Visit.Push(true);
if (right != null) { stack.Push(right); stackReady4Visit.Push(false); }
if (left != null) { stack.Push(left); stackReady4Visit.Push(false); }
}
}
}
}
public abstract class NodeWorker<T>
{
public abstract void DoActionOnNode(BinaryTreeNode<T> node);
}
前中后序遍历二叉树
以上三种遍历实现代码行数一模一样,如同递归遍历一样,只有三行核心代码的先后顺序有区别。用原作者的话解释就是:"得以统一三种更简单的非递归遍历方法的基本思想:有重合元素的局部有序一定能导致整体有序。基于这种思想,我就构思三种非递归遍历的统一思想:不管是前序,中序,后序,只要我能保证对每个结点而言,该结点,其左子结点,其右子结点都满足以前序/中序/后序的访问顺序,整个二叉树的这种三结点局部有序一定能保证整体以前序/中序/后序访问,因为相邻的局部必有重合的结点,即一个局部的"根"结点是另外一个局部的"子"结点。"。
public class BinaryTree<T>
{
BinaryTreeNode<T> Node { get;set; }
public BinaryTree(BinaryTreeNode<T> node)
{
this.Node = node;
}
public void Traverse(TraverseOrder order, NodeWorker<T> worker)
{
if (worker == null) { return; }
var node = this.Node;
if (node == null) { return; }
switch (order)
{
case TraverseOrder.Preorder:
node.Traverse(order, worker);
break;
case TraverseOrder.Inorder:
node.Traverse(order, worker);
break;
case TraverseOrder.Postorder:
node.Traverse(order, worker);
break;
case TraverseOrder.Layer:
TraverseLayer(worker);
break;
default:
break;
}
}
private void TraverseLayer(NodeWorker<T> worker)
{
var queue = new Queue<BinaryTreeNode<T>>();
queue.Enqueue(this.Node);
while (queue.Count > 0)
{
var element = queue.Dequeue();
if (element != null)
{
worker.DoActionOnNode(element);
var left = element.Left;
var right = element.Right;
if (left != null) { queue.Enqueue(left); }
if (right != null) { queue.Enqueue(right); }
}
}
}
}
层次遍历
473

被折叠的 条评论
为什么被折叠?



