算法学习,单链表 C# 泛型实现

这个链表没有暴露node接口,而是把链表本身包装成了一个Collection和List,实现了ICollection<T>, IEnumerable<T>, IList<T>接口,写的过程中参考了BCL中的实现以及Wintellect.PowerCollection的实现以及写法。并且初步通过测试。

namespace  FengChen.Practices
{
    
internal   class  ListNode < T >
    {
        
public  T Item;  //  Element item
         public  ListNode < T >  Next;

        
public  ListNode(T value) :  this () {  this .Item  =  value; }
        
internal  ListNode() {  this .Next  =   null ; }
    }

    
public   class  LinkList < T >  : ICollection < T > , IEnumerable < T > , IList < T >
    {
        
private  ListNode < T >  m_Head;
        
private  ListNode < T >  m_End;
       
        
private  Int32 m_Count;

        EqualityComparer
< T >  m_Comparer  =  EqualityComparer < T > .Default;

        
#region  ctor
        
public  LinkList()
        {
            m_Head 
=   new  ListNode < T > ();
            m_End 
=  m_Head;
        }

        
public  LinkList(T[] array)
            : 
this ()
        {
            
if  (array  ==   null throw   new  ArgumentNullException( " array " );
            
foreach  (T item  in  array)  this .Add(item);
        }
        
#endregion

        
#region  Utility methods
        
public   bool  IsEmpty {  get  {  return  m_Head.Next  ==   null ; } }

        
private  ListNode < T >  Find(T value,  out  Int32 index)
        {
            ListNode
< T >  node  =  m_Head.Next;
            index 
=   0 ;

            
while  (node  !=   null   &&   ! m_Comparer.Equals(value, node.Item))
            {
                node 
=  node.Next;
                index
++ ;
            }
            
if  (node  ==   null ) index  =   - 1 ;
            
return  node;
        }

        
private  ListNode < T >  FindPrevious(T value)
        {
            ListNode
< T >  node  =  m_Head;

            
while  (node.Next  !=   null   &&   ! m_Comparer.Equals(value, node.Next.Item))
                node 
=  node.Next;
            
return  node;
        }
        
#endregion

        
#region  ICollection<T> Members
        
public   void  Add(T item)   //  Add the item at end
        {
            ListNode
< T >  node  =   new  ListNode < T > (item);
            m_End.Next 
=  node;
            m_End 
=  node;
            m_Count
++ ;
        }

        
public   void  Clear()
        {
            ListNode
< T >  pos, temp;
            pos 
=  m_Head;
            
while  (pos  !=   null )
            {
                temp 
=  pos.Next;
                pos.Next 
=   null ;
                pos 
=  temp;
            }
            m_Count 
=   0 ;
            m_End 
=  m_Head;
        }

        
public   bool  Contains(T item) 
        {
            Int32 i 
=   0 ;
            
return   this .Find(item,  out  i)  !=   null ;
        }

        
public   void  CopyTo(T[] array,  int  index)
        {
            
if  (array  ==   null
                
throw   new  ArgumentNullException( " array " );
            
            
if  ((index  <   0 ||  (index  >=  array.Length))
                
throw   new  ArgumentOutOfRangeException( " index " , index,  " Please check the index value! " );
            
            
if  ((array.Length  -  index)  <   this .Count)
                
throw   new  ArgumentException( " Insufficient Space! " );

            ListNode
< T >  node  =  m_Head.Next;
            
while (node  !=   null )
            {
                array[index
++ =  node.Item;
                node 
=  node.Next;
            }
        }

        
public   int  Count {  get  {  return  m_Count; } }

        
public   bool  IsReadOnly {  get  {  return   false ; } }

        
public   bool  Remove(T item)
        {
            ListNode
< T >  preNode  =   this .FindPrevious(item);
            ListNode
< T >  tempNode  =   null ;
            
if  (preNode.Next  !=   null //  item is found
            {
                
if  (m_End  ==  preNode.Next) m_End  =  preNode;
                
                tempNode 
=  preNode.Next;  //  node to be deleted
                preNode.Next  =  tempNode.Next;
                tempNode 
=   null ;
                m_Count
-- ;
                
return   true ;
            }
            
return   false ;
        }
        
#endregion

        
#region  IEnumerable<T> Members
        
public  IEnumerator < T >  GetEnumerator()
        {
            ListNode
< T >  node  =   this .m_Head.Next;
            
while (node  !=   null )
            {
                
yield   return  node.Item;
                node 
=  node.Next;
            }
        }
        
#endregion

        
#region  IEnumerable Members
        IEnumerator IEnumerable.GetEnumerator()
        {
            
return   this .GetEnumerator();
        }
        
#endregion

        
///   <summary>
        
///  StreamWriter = new StreamWriter(Console.OpenStandardOutput());
        
///   </summary>
        
///   <param name="writer"></param>
         public   void  Display(StringWriter writer)
        {
            
//  Use it like this
            ListNode < T >  p  =  m_Head.Next;
            writer.Write(
" The List Item is:  " );
            
while  (p  !=   null )
            {
                writer.Write(
" {0}--> " , p.Item);
                p 
=  p.Next;
            }
            writer.Write(
" NULL " );
            writer.Write(Environment.NewLine);
        }

        
public   override  String ToString ()
        {
            StringBuilder sb 
=   new  StringBuilder();
            StringWriter writer 
=   new  StringWriter(sb);
            
            
this .Display (writer);
            writer.Close ();
            
return  sb.ToString();
        }

        
#region  IList<T> Members
        
public   int  IndexOf(T item)
        {
            Int32 index 
=   0 ;
            
this .Find(item,  out  index);
            
return  index;
        }

        
public   void  Insert( int  index, T item)
        {
            
if  (index  <   0   ||  index  >=   this .m_Count)
                
throw   new  ArgumentOutOfRangeException( " index " , index,  " Index value is out of range, please check! " );

            ListNode
< T >  previousNode  =   this .m_Head.Next;
            ListNode
< T >  node  =   new  ListNode < T > (item);
            
while ( index --   >   0  ) previousNode  =  previousNode.Next;

            node.Next 
=  previousNode.Next;
            previousNode.Next 
=  node;

            
if  (m_End.Next  !=   null ) m_End  =  node;
            m_Count
++ ;
        }

        
public   void  RemoveAt( int  index)
        {
            
if  (index  <   0   ||  index  >=   this .m_Count)
                
throw   new  ArgumentOutOfRangeException( " index " , index,  " Index value is out of range, please check! " );

            ListNode
< T >  previousNode  =   this .m_Head;
            
while  (index --   >   0 ) previousNode  =  previousNode.Next;

            ListNode
< T >  node  =  previousNode.Next;
            
if  (node  ==   null return ;
            
if  (node  ==  m_End) m_End  =  previousNode;

            previousNode.Next 
=  node.Next;
            node.Next 
=   null ;
            node 
=   null ;

            m_Count
-- ;
        }

        
private  ListNode < T >  GetNode( int  index)
        {
            
if  (index  <   0   ||  index  >=   this .m_Count)
                
throw   new  ArgumentOutOfRangeException( " index " , index,  " Index value is out of range, please check! " );

            ListNode
< T >  node  =   this .m_Head.Next;
            
while  (index --   >   0 ) node  =  node.Next;

            
return  node;
        }        

        
public  T  this [ int  index]
        {
            
get  {  return   this .GetNode(index).Item; }
            
set  {  this .GetNode(index).Item  =  value; }
        }

        
#endregion
    }
}

欢迎多提意见。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值