Volunteer .NET Evangelist

A well oiled machine can’t run efficiently, if you grease it with water.
  首页 :: 联系 :: 订阅 订阅 :: 管理

SingleLinkedList Implementation

Posted on 2006-04-23 23:43 Sheva 阅读(...) 评论(...) 编辑 收藏
ILinkedList interface definition
using System;
using System.Collections.Generic;

namespace Sheva.Collections
{
    
public interface ILinkedList<T>
    {
        Boolean IsEmpty { 
get;}
        
void AddFirst(T item);
        
void AddLast(T item);
        T First { 
get;}
        T Last { 
get;}
        T RemoveFirst();
        T RemoveLast();
        IEnumerable
<T> Backwards { get;}
        IEnumerable
<T> Forwards { get;}
    }
}

SingleLinkedList implementation
using System;
using System.Collections;
using System.Collections.Generic;

namespace Sheva.Collections
{
    
public class SingleLinkedList<T> : ILinkedList<T>, ICollection<T>
    {
        
private Node firstNode;
        
private Node lastNode;

        
/// <summary>
        
/// Create an empty <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        public SingleLinkedList()
        {
            firstNode 
= lastNode = null;
        }

        
#region ILinkedList<T> Members

        
/// <summary>
        
/// Check whether the specified <see cref="SingleLinkedList">SingleLinkedList</see> is empty.
        
/// </summary>
        public Boolean IsEmpty
        {
            
get { return firstNode == null; }
        }

        
/// <summary>
        
/// Gets the first node of the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        public T First
        {
            
get
            {
                
if (IsEmpty) throw new InvalidOperationException("The list is empty!");
                
return firstNode.Value;
            }
        }

        
/// <summary>
        
/// Gets the last node of the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        public T Last
        {
            
get
            {
                
if (IsEmpty) throw new InvalidOperationException("The list is empty!");
                
return lastNode.Value;
            }
        }

        
/// <summary>
        
/// Adds a new value at the start of the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        
/// <param name="value">The value to add at the start of the <see cref="SingleLinkedList">SingleLinkedList</see>.</param>
        public void AddFirst(T value)
        {
            Node newNode 
= new Node();
            newNode.Value 
= value;

            
if (IsEmpty)
            {
                firstNode 
= lastNode = newNode;
            }
            
else
            {
                newNode.Next 
= firstNode;
                firstNode 
= newNode;
            }
        }

        
/// <summary>
        
/// Adds a new value at the end of the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        
/// <param name="value">The value to add at the start of the <see cref="SingleLinkedList">SingleLinkedList</see>.</param>
        public void AddLast(T value)
        {
            Node newNode 
= new Node();
            newNode.Value 
= value;

            
if (IsEmpty)
            {
                firstNode 
= lastNode = newNode;
            }
            
else
            {
                lastNode.Next 
= newNode;
                lastNode 
= newNode;
            }
        }

        
/// <summary>
        
/// Removes the node at the start of the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        
/// <returns>the value removed from the <see cref="SingleLinkedList">SingleLinkedList</see>.</returns>
        public T RemoveFirst()
        {
            
if (IsEmpty) throw new InvalidOperationException("The list is empty!");

            T removedValue 
= firstNode.Value;
            
if (firstNode == lastNode) firstNode = lastNode = null;
            firstNode 
= firstNode.Next;

            
return removedValue;
        }

        
/// <summary>
        
/// Removes the node at the end of the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        
/// <returns>the value removed from the <see cref="SingleLinkedList">SingleLinkedList</see>.</returns>
        public T RemoveLast()
        {
            
if (IsEmpty) throw new InvalidOperationException("The list is empty!");

            T removedValue 
= lastNode.Value;
            
if (firstNode == lastNode)
            {
                firstNode 
= lastNode = null;
            }

            
// Locate new last node.
            Node currentNode = firstNode;
            
while (currentNode.Next != lastNode)
            {
                currentNode 
= currentNode.Next;
            }

            
// Remove last node.
            lastNode = currentNode;
            currentNode.Next 
= null;

            
return removedValue;
        }

        IEnumerable
<T> ILinkedList<T>.Backwards
        {
            
get { throw new NotImplementedException("The list doesn't support this operation!"); }
        }

        
/// <summary>
        
/// Returns an enumerator that forwardly iterates through the <see cref="SingleLinkedList">SingleLinkedList</see>
        
/// </summary>
        
/// <returns>An <see cref="IEnumerable<T>">Enumerable</see> for the LinkedList. </returns>
        public IEnumerable<T> Forwards
        {
            
get
            {
                Node current 
= firstNode;
                
while (current != null)
                {
                    yield 
return current.Value;
                    current 
= current.Next;
                }
            }
        }

        
#endregion

        
#region ICollection<T> Members

        
void ICollection<T>.Add(T value)
        {
            
this.AddLast(value);
        }

        
/// <summary>
        
/// Removes all nodes from the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        public void Clear()
        {
            firstNode 
= lastNode = null;
        }

        
/// <summary>
        
/// Determines whether a value is in the <see cref="SingleLinkedList">SingleLinkedList</see>
        
/// </summary>
        
/// <param name="value">The value to locate in the <see cref="SingleLinkedList">SingleLinkedList</see>.</param>
        
/// <returns>true if value is found in the <see cref="SingleLinkedList">SingleLinkedList</see>; otherwise, false. </returns>
        public Boolean Contains(T value)
        {
            
if (IsEmpty) throw new InvalidOperationException("The list is empty!");

            Node currentNode 
= firstNode;
            
while (currentNode != null)
            {
                
if (currentNode.Value.Equals(value)) return true;

                currentNode 
= currentNode.Next;
            }

            
return false;
        }

        
/// <summary>
        
/// Copies the entire <see cref="SingleLinkedList">SingleLinkedList</see> to a compatible one-dimensional <see cref="System.Array">Array</see>, starting at the specified index of the target array.
        
/// </summary>
        
/// <param name="array">The one-dimensional <see cref="System.Array">Array</see> that is the destination of the elements copied from <see cref="SingleLinkedList">SingleLinkedList</see>. The array must have zero-based indexing.</param>
        
/// <param name="index">The zero-based index in array at which copying begins.</param>
        public void CopyTo(T[] array, Int32 index)
        {
            
if (array == nullthrow new ArgumentNullException("array is a null reference ");
            
if (index < 0throw new ArgumentOutOfRangeException("arrayIndex is less than zero.");
            
if (index >= array.Length) throw new ArgumentException("arrayIndex is equal to or greater than the length of array");
            
if (this.Count > (array.Length - index)) throw new ArgumentException("The number of elements in the source list is greater than the available space from index to the end of the destination array.");

            Int32 offset 
= 0;
            Node currentNode 
= firstNode;
            
while (currentNode != null)
            {
                array[index 
+ offset] = currentNode.Value;
                currentNode 
= currentNode.Next;
                offset
++;
            }
        }

        
/// <summary>
        
/// Gets the number of nodes actually contained in the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        public Int32 Count
        {
            
get
            {
                Int32 count 
= 0;
                Node currentNode 
= firstNode;
                
while (currentNode != null)
                {
                    currentNode 
= currentNode.Next;
                    count
++;
                }

                
return count;
            }
        }

        
/// <summary>
        
/// 
        
/// </summary>
        public Boolean IsReadOnly
        {
            
get { return false; }
        }

        
/// <summary>
        
/// Removes the first occurrence of value from the <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </summary>
        
/// <param name="value">The value to remove from the <see cref="SingleLinkedList">SingleLinkedList</see>.</param>
        
/// <returns>
        
/// true if the element containing value is successfully removed; otherwise, false.
        
/// This method also returns false if value was not found in the original <see cref="SingleLinkedList">SingleLinkedList</see>.
        
/// </returns>
        public Boolean Remove(T value)
        {
            
if (IsEmpty) throw new InvalidOperationException("The list is empty!");

            Node currentNode 
= firstNode;
            
while (currentNode != null)
            {
                
if (currentNode.Next.Value.Equals(value))
                {
                    currentNode.Next 
= currentNode.Next.Next;
                    
return true;
                }

                currentNode 
= currentNode.Next;
            }

            
return false;
        }

        
#endregion

        
#region IEnumerable<T> Members

        
/// <summary>
        
/// Returns an enumerator that forwardly iterates through the <see cref="SingleLinkedList">SingleLinkedList</see>
        
/// </summary>
        
/// <returns>An <see cref="IEnumerator&lt;T&gt;>">Enumerator</see> for the <see cref="SingleLinkedList">SingleLinkedList</see>.</returns>
        public IEnumerator<T> GetEnumerator()
        {
            
return Forwards.GetEnumerator();
        }

        
#endregion

        
#region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            
return Forwards.GetEnumerator();
        }

        
#endregion
        
        
private class Node
        {
            
public T Value;
            
public Node Next;
        }
    }
}