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

这个链表没有暴露node接口,而是把链表本身包装成了一个Collection和List,实现了ICollection , IEnumerable , IList 接口,写的过程中参考了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

    }
}

欢迎多提意见。

点赞