这一节是关于二叉树的遍历的,常用的有四种遍历二叉树,分别为先序,中序,后序,层次遍历二叉树。利用我们上一节生成的二叉树举例,递归是我们比较常用的方法,看起来比较易懂,代码也比较优美。非递归算法则用另外一种方式对其进行实现。
   递归算法:
   先序遍历:根,左,右

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();
        }

二叉树的排序方法还远远不止这些,本文中给出这些算法也只是给了一个开头,对于树算法的研究远远没有尽头。

Posted on 2006-09-27 15:31  GerryJiang  阅读(861)  评论(0编辑  收藏  举报