现在的位置: 首页 > 综合 > 正文

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

2018年04月06日 ⁄ 综合 ⁄ 共 6818字 ⁄ 字号 评论关闭
这个链表没有暴露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
    }
}

欢迎多提意见。

抱歉!评论已关闭.