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

本文介绍了一种自定义链表的实现方式,该链表实现了ICollection、IEnumerable和IList接口,支持基本的增删查改操作,并通过了初步测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个链表没有暴露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 == nullthrow 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 == nullreturn;
            
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、付费专栏及课程。

余额充值