二叉树的C#实现

1. 二叉树结构:

 

ExpandedBlockStart.gif 代码
     public   class  TwoXTree
    {
        
public   string  Data {  set get ; }
        
public  TwoXTree LeftChild {  set get ; }
        
public  TwoXTree RightChild {  set get ; }

        
public  TwoXTree()
        {
        }
    }

 

2. 创建(这里直接通过输入广义表字符串来实现,为了简单起见,这里将Data域类型设置为char):

 

ExpandedBlockStart.gif 代码
         ///   <summary>
        
///  Create a 2XTree
        
///   </summary>
        
///   <param name="treeString"> eg: A(B(C,D),E(,F(G,)))$ </param>
        
///   <returns></returns>
         public   static  TwoXTree CreateTwoXTree( string  treeString)
        {
            
if  (String.IsNullOrEmpty(treeString)  ||  treeString.Equals( " $ " ))
            {
                
return   null ;
            }

            var charArray 
=  treeString.ToCharArray();
            
if  (charArray.Count(item  =>  item  ==   ' ( ' !=  charArray.Count(item  =>  item  ==   ' ) ' ))
            {
                
throw   new  ArgumentException( " treeString " );
            }

            Stack
< TwoXTree >  stack  =   new  Stack < TwoXTree > ();
            TwoXTree root 
=   new  TwoXTree
            {
                Data 
=  treeString[ 0 ].ToString()
            };
            stack.Push(root);

            TwoXTree parent 
=  root, node  =  root;            
            
bool  isLeftNode  =   true ;
            
for  ( int  i  =   1 ; i  <  treeString.Length; i ++ )
            {
                
switch  (treeString[i])
                {
                    
case   ' $ ' :
                        
break ;
                    
case   ' ( ' :
                        stack.Push(node);
                        parent 
=  node;
                        isLeftNode 
=   true ;
                        
break ;
                    
case   ' ) ' :
                        stack.Pop();
                        parent 
=  stack.Peek();
                        
break ;
                    
case   ' , ' :
                        isLeftNode 
=   false ;
                        
break ;
                    
default :                        
                        node 
=   new  TwoXTree
                        {
                            Data 
=  treeString[i].ToString()
                        };
                        
                        
if  (parent  !=   null )
                        {
                            
if  (isLeftNode)
                            {
                                parent.LeftChild 
=  node;
                            }
                            
else
                            {
                                parent.RightChild 
=  node;
                            }
                        }
                        
break ;
                }
            }

            
return  root;
        }

 

3. 遍历:

 

ExpandedBlockStart.gif 代码
         private   void  Visit(TwoXTree treeNode)
        {
            
if  (treeNode  ==   null )
                
return ;

            Console.Write(
"  ---> {0}  " , treeNode.Data);
        }

        
#region  Preorder traversal
        
public   void  Preorder_Recursion()
        {
            Visit(
this );
            
if  ( this .LeftChild  !=   null )
            {
                
this .LeftChild.Preorder_Recursion();
            }
            
if  ( this .RightChild  !=   null )
            {
                
this .RightChild.Preorder_Recursion();
            }
        }

        
public   void  Preorder()
        {
            Stack
< TwoXTree >  stack  =   new  Stack < TwoXTree > ();
            Stack
< bool >  stack2  =   new  Stack < bool > ();
            TwoXTree node 
=   this ;
            
bool  flag;   //  used to check if already visit both the left child and the right child of current node

            
do
            {
                
while  (node  !=   null )
                {
                    Visit(node);
                    stack.Push(node);
                    stack2.Push(
false );

                    node 
=  node.LeftChild;
                }

                node 
=  stack.Pop();
                flag 
=  stack2.Pop();
                
if  (flag)
                {
                    node 
=   null ;
                }
                
else
                {
                    stack.Push(node);
                    stack2.Push(
true );

                    node 
=  node.RightChild;
                }
            } 
while  (node  !=   null   ||  stack.Count  >   0 );
        }
        
#endregion

        
#region  Inorder
        
public   void  Inorder_Recursion()
        {
            
if  ( this .LeftChild  !=   null )
            {
                
this .LeftChild.Inorder_Recursion();
            }
            Visit(
this );
            
if  ( this .RightChild  !=   null )
            {
                
this .RightChild.Inorder_Recursion();
            }
        }

        
public   void  Inorder()
        {
            Stack
< TwoXTree >  stack  =   new  Stack < TwoXTree > ();
            Stack
< bool >  stack2  =   new  Stack < bool > ();
            TwoXTree node 
=   this ;
            
bool  flag;

            
do
            {
                
while  (node  !=   null )
                {
                    stack.Push(node);
                    stack2.Push(
false );

                    node 
=  node.LeftChild;
                }

                node 
=  stack.Pop();
                flag 
=  stack2.Pop();
                
if  (flag)
                {
                    node 
=   null ;
                }
                
else
                {
                    Visit(node);
                    stack.Push(node);
                    stack2.Push(
true );

                    node 
=  node.RightChild;
                }
            } 
while  (node  !=   null   ||  stack.Count  >   0 );
        }
        
#endregion

        
#region  Posorder
        
public   void  Posorder_Recursion()
        {
            
if  ( this .LeftChild  !=   null )
            {
                
this .LeftChild.Posorder_Recursion();
            }
            
if  ( this .RightChild  !=   null )
            {
                
this .RightChild.Posorder_Recursion();
            }
            Visit(
this );
        }

        
public   void  Posorder()
        {
            Stack
< TwoXTree >  stack  =   new  Stack < TwoXTree > ();
            Stack
< bool >  stack2  =   new  Stack < bool > ();
            TwoXTree node 
=   this ;
            
bool  flag;

            
do
            {
                
while  (node  !=   null )
                {
                    stack.Push(node);
                    stack2.Push(
false );

                    node 
=  node.LeftChild;
                }

                node 
=  stack.Pop();
                flag 
=  stack2.Pop();
                
if  (flag)
                {
                    Visit(node);
                    node 
=   null ;
                }
                
else
                {
                    stack.Push(node);
                    stack2.Push(
true );

                    node 
=  node.RightChild;
                }

            } 
while  (node  !=   null   ||  stack.Count  >   0 );
        }
        
#endregion

        
#region  Layer Order
        
public   void  LayerOrder()
        {
            Queue
< TwoXTree >  queue  =   new  Queue < TwoXTree > ();            
            queue.Enqueue(
this );

            TwoXTree node;
            
while  (queue.Count  >   0 )
            {
                node 
=  queue.Dequeue();

                Visit(node);
                
if  (node.LeftChild  !=   null )
                    queue.Enqueue(node.LeftChild);
                
if  (node.RightChild  !=   null )
                    queue.Enqueue(node.RightChild);
            }
        }
        
#endregion

 

4. 统计总节点数:

 

ExpandedBlockStart.gif 代码
         #region  Get total count
        
///   <summary>
        
///  Get total count by recursion
        
///   </summary>
        
///   <returns></returns>
         public   int  GetTotalCount_Recursion()
        {
            
int  totalCount  =   1 ;

            
if  ( this .LeftChild  !=   null )
                totalCount 
+=   this .LeftChild.GetTotalCount_Recursion();
            
if  ( this .RightChild  !=   null )
                totalCount 
+=   this .RightChild.GetTotalCount_Recursion();

            
return  totalCount;
        }

        
///   <summary>
        
///  Get total count
        
///   </summary>
        
///   <returns></returns>
         public   int  GetTotalCount()
        {
            Queue
< TwoXTree >  queue  =   new  Queue < TwoXTree > ();
            TwoXTree node 
=   this ;
            
int  totalCount  =   0 ;
            
while  (node  !=   null )
            {
                
++ totalCount;

                
if  (node.LeftChild  !=   null )
                    queue.Enqueue(node.LeftChild);
                
if  (node.RightChild  !=   null )
                    queue.Enqueue(node.RightChild);

                
if  (queue.Count  >   0 )
                {
                    node 
=  queue.Dequeue();
                }
                
else
                {
                    node 
=   null ;
                }
            }

            
return  totalCount;
        }
        
#endregion

 

5. 树的最大层数:

 

ExpandedBlockStart.gif 代码
         #region  Get max length
        
public   int  GetMaxLength_Recursion()
        {
            
int  left  =   0 , right  =   0 ;
            
if  ( this .LeftChild  !=   null )
                left 
=   this .LeftChild.GetMaxLength_Recursion();
            
if  ( this .RightChild  !=   null )
                right 
=   this .RightChild.GetMaxLength_Recursion();

            
return  left  >  right  ?  left  +   1  : right  +   1 ;
        }

        
public   int  GetMaxLength()
        {
            Queue
< TwoXTree >  treeQueue  =   new  Queue < TwoXTree > ();
            Queue
< int >  lengthQueue  =   new  Queue < int > ();

            TwoXTree node 
=   this ;
            
int  length  =   0 ;
            treeQueue.Enqueue(node);
            lengthQueue.Enqueue(
1 );
            
while  (treeQueue.Count  >   0 )
            {
                node 
=  treeQueue.Dequeue();
                length 
=  lengthQueue.Dequeue();

                
if  (node.LeftChild  !=   null )
                {
                    treeQueue.Enqueue(node.LeftChild);
                    lengthQueue.Enqueue(length 
+   1 );
                }
                
if  (node.RightChild  !=   null )
                {
                    treeQueue.Enqueue(node.RightChild);
                    lengthQueue.Enqueue(length 
+   1 );
                }
            }

            
return  length;
        }
        
#endregion

 

 

6. 测试:

 

ExpandedBlockStart.gif 代码
             string  tree  =   " A(B(C(E(H,),F),D(,I)),J(K,L(M(,N),))) " ;
            TwoXTree twoXTree 
=  TwoXTree.CreateTwoXTree(tree);

            
int  totalCount  =  twoXTree.GetTotalCount();
            
int  totalCountRecursion  =  twoXTree.GetTotalCount_Recursion();

            
int  maxLength  =  twoXTree.GetMaxLength();
            
int  maxLengthRecursion  =  twoXTree.GetMaxLength_Recursion();

            Console.WriteLine(
" Preorder:  " );
            twoXTree.Preorder_Recursion();
            Console.WriteLine();
            twoXTree.Preorder();
            Console.WriteLine();

            Console.WriteLine(
" Inorder:  " );
            twoXTree.Inorder_Recursion();
            Console.WriteLine();
            twoXTree.Inorder();
            Console.WriteLine();

            Console.WriteLine(
" Posorder:  " );
            twoXTree.Posorder_Recursion();
            Console.WriteLine();
            twoXTree.Posorder();
            Console.WriteLine();

            Console.WriteLine(
" Layer Order:  " );
            twoXTree.LayerOrder();
            Console.WriteLine();

 

 Download

转载于:https://www.cnblogs.com/Langzi127/archive/2010/07/18/1780255.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值