.NET Framework Class Library
LinkedList<(Of <(T>)>) Class

Represents a doubly linked list.

Namespace:  System.Collections.Generic
Assembly:  System (in System.dll)
Syntax

Visual Basic (Declaration)
<SerializableAttribute> _
<ComVisibleAttribute(False)> _
Public Class LinkedList(Of T) _
    Implements ICollection(Of T), IEnumerable(Of T),  _
    ICollection, IEnumerable, ISerializable, IDeserializationCallback
Visual Basic (Usage)
Dim instance As LinkedList(Of T)
C#
[SerializableAttribute]
[ComVisibleAttribute(false)]
public class LinkedList<T> : ICollection<T>, 
    IEnumerable<T>, ICollection, IEnumerable, ISerializable, IDeserializationCallback
Visual C++
[SerializableAttribute]
[ComVisibleAttribute(false)]
generic<typename T>
public ref class LinkedList : ICollection<T>, 
    IEnumerable<T>, ICollection, IEnumerable, ISerializable, IDeserializationCallback
JScript
JScript does not support generic types or methods.

Type Parameters

T

Specifies the element type of the linked list.

Remarks

LinkedList<(Of <(T>)>) is a general-purpose linked list. It supports enumerators and implements the ICollection interface, consistent with other collection classes in the .NET Framework.

LinkedList<(Of <(T>)>) provides separate nodes of type LinkedListNode<(Of <(T>)>), so insertion and removal are O(1) operations.

You can remove nodes and reinsert them, either in the same list or in another list, which results in no additional objects allocated on the heap. Because the list also maintains an internal count, getting the Count property is an O(1) operation.

Each node in a LinkedList<(Of <(T>)>) object is of the type LinkedListNode<(Of <(T>)>). Because the LinkedList<(Of <(T>)>) is doubly linked, each node points forward to the Next node and backward to the Previous node.

Lists that contain reference types perform better when a node and its value are created at the same time. LinkedList<(Of <(T>)>) accepts nullNothingnullptra null reference (Nothing in Visual Basic) as a valid Value property for reference types and allows duplicate values.

If the LinkedList<(Of <(T>)>) is empty, the First and Last properties contain nullNothingnullptra null reference (Nothing in Visual Basic).

The LinkedList<(Of <(T>)>) class does not support chaining, splitting, cycles, or other features that can leave the list in an inconsistent state. The list remains consistent on a single thread. The only multithreaded scenario supported by LinkedList<(Of <(T>)>) is multithreaded read operations.

Examples

The following code example demonstrates many features of the LinkedList<(Of <(T>)>) class.

Visual Basic
Imports System
Imports System.Text
Imports System.Collections.Generic
Public Class Example

    Public Shared Sub Main()
        ' Create the link list.
        Dim words() As String = {"the", "fox", _
            "jumped", "over", "the", "dog"}
        Dim sentence As New LinkedList(Of String)(words)
        Console.WriteLine("sentence.Contains(""jumped"") = {0}", _
            sentence.Contains("jumped"))
        Display(sentence, "The linked list values:")
        ' Add the word 'today' to the beginning of the linked list.
        sentence.AddFirst("today")
        Display(sentence, "Test 1: Add 'today' to beginning of the list:")
        ' Move the first node to be the last node.
        Dim mark1 As LinkedListNode(Of String) = sentence.First
        sentence.RemoveFirst()
        sentence.AddLast(mark1)
        Display(sentence, "Test 2: Move first node to be last node:")
        ' Change the last node be 'yesterday'.
        sentence.RemoveLast()
        sentence.AddLast("yesterday")
        Display(sentence, "Test 3: Change the last node to 'yesterday':")
        ' Move the last node to be the first node.
        mark1 = sentence.Last
        sentence.RemoveLast()
        sentence.AddFirst(mark1)
        Display(sentence, "Test 4: Move last node to be first node:")
        ' Indicate, by using parentheisis, the last occurence of 'the'.
        sentence.RemoveFirst()
        Dim current As LinkedListNode(Of String) = sentence.FindLast("the")
        IndicateNode(current, "Test 5: Indicate last occurence of 'the':")
        ' Add 'lazy' and 'old' after 'the' (the LinkedListNode named current).
        sentence.AddAfter(current, "old")
        sentence.AddAfter(current, "lazy")
        IndicateNode(current, "Test 6: Add 'lazy' and 'old' after 'the':")
        ' Indicate 'fox' node.
        current = sentence.Find("fox")
        IndicateNode(current, "Test 7: Indicate the 'fox' node:")
        ' Add 'quick' and 'brown' before 'fox':
        sentence.AddBefore(current, "quick")
        sentence.AddBefore(current, "brown")
        IndicateNode(current, "Test 8: Add 'quick' and 'brown' before 'fox':")
        ' Keep a reference to the current node, 'fox',
        ' and to the previous node in the list. Indicate the 'dog' node.
        mark1 = current
        Dim mark2 As LinkedListNode(Of String) = current.Previous
        current = sentence.Find("dog")
        IndicateNode(current, "Test 9: Indicate the 'dog' node:")
        ' The AddBefore method throws an InvalidOperationException
        ' if you try to add a node that already belongs to a list.
        Console.WriteLine("Test 10: Throw exception by adding node (fox) already in the list:")
        Try
            sentence.AddBefore(current, mark1)
        Catch ex As InvalidOperationException
            Console.WriteLine("Exception message: {0}", ex.Message)
        End Try
        Console.WriteLine()
        ' Remove the node referred to by mark1, and then add it
        ' before the node referred to by current.
        ' Indicate the node referred to by current.
        sentence.Remove(mark1)
        sentence.AddBefore(current, mark1)
        IndicateNode(current, "Test 11: Move a referenced node (fox) before the current node (dog):")
        ' Remove the node referred to by current. 
        sentence.Remove(current)
        IndicateNode(current, "Test 12: Remove current node (dog) and attempt to indicate it:")
        ' Add the node after the node referred to by mark2.
        sentence.AddAfter(mark2, current)
        IndicateNode(current, "Test 13: Add node removed in test 11 after a referenced node (brown):")
        ' The Remove method finds and removes the
        ' first node that that has the specified value.
        sentence.Remove("old")
        Display(sentence, "Test 14: Remove node that has the value 'old':")
        ' When the linked list is cast to ICollection(Of String),
        ' the Add method adds a node to the end of the list.
        sentence.RemoveLast()
        Dim icoll As ICollection(Of String) = sentence
        icoll.Add("rhinoceros")
        Display(sentence, "Test 15: Remove last node, cast to ICollection, and add 'rhinoceros':")
        Console.WriteLine("Test 16: Copy the list to an array:")
        ' Create an array with the same number of
        ' elements as the inked list.
        Dim sArray() As String = New String((sentence.Count) - 1) {}
        sentence.CopyTo(sArray, 0)
        For Each s As String In sArray
            Console.WriteLine(s)
        Next
        ' Release all the nodes.
        sentence.Clear()
        Console.WriteLine()
        Console.WriteLine("Test 17: Clear linked list. Contains 'jumped' = {0}", sentence.Contains("jumped"))
        Console.ReadLine()
    End Sub

    Private Shared Sub Display(ByVal words As LinkedList(Of String), ByVal test As String)
        Console.WriteLine(test)
        For Each word As String In words
            Console.Write((word + " "))
        Next
        Console.WriteLine()
        Console.WriteLine()
    End Sub

    Private Shared Sub IndicateNode(ByVal node As LinkedListNode(Of String), ByVal test As String)
        Console.WriteLine(test)
        If IsNothing(node.List) Then
            Console.WriteLine("Node '{0}' is not in the list." & vbLf, node.Value)
            Return
        End If
        Dim result As StringBuilder = New StringBuilder(("(" _
                        + (node.Value + ")")))
        Dim nodeP As LinkedListNode(Of String) = node.Previous

        While (Not (nodeP) Is Nothing)
            result.Insert(0, (nodeP.Value + " "))
            nodeP = nodeP.Previous

        End While
        node = node.Next

        While (Not (node) Is Nothing)
            result.Append((" " + node.Value))
            node = node.Next

        End While
        Console.WriteLine(result)
        Console.WriteLine()
    End Sub
End Class
'This code example produces the following output:
'
'The linked list values:
'the fox jumped over the dog 
'Test 1: Add 'today' to beginning of the list:
'today the fox jumped over the dog 
'Test 2: Move first node to be last node:
'the fox jumped over the dog today 
'Test 3: Change the last node to 'yesterday':
'the fox jumped over the dog yesterday 
'Test 4: Move last node to be first node:
'yesterday the fox jumped over the dog 
'Test 5: Indicate last occurence of 'the':
'the fox jumped over (the) dog
'Test 6: Add 'lazy' and 'old' after 'the':
'the fox jumped over (the) lazy old dog
'Test 7: Indicate the 'fox' node:
'the (fox) jumped over the lazy old dog
'Test 8: Add 'quick' and 'brown' before 'fox':
'the quick brown (fox) jumped over the lazy old dog
'Test 9: Indicate the 'dog' node:
'the quick brown fox jumped over the lazy old (dog)
'Test 10: Throw exception by adding node (fox) already in the list:
'Exception message: The LinkedList node belongs a LinkedList.
'Test 11: Move a referenced node (fox) before the current node (dog):
'the quick brown jumped over the lazy old fox (dog)
'Test 12: Remove current node (dog) and attempt to indicate it:
'Node 'dog' is not in the list.
'Test 13: Add node removed in test 11 after a referenced node (brown):
'the quick brown (dog) jumped over the lazy old fox
'Test 14: Remove node that has the value 'old':
'the quick brown dog jumped over the lazy fox 
'Test 15: Remove last node, cast to ICollection, and add 'rhinoceros':
'the quick brown dog jumped over the lazy rhinoceros 
'Test 16: Copy the list to an array:
'the
'quick
'brown
'dog
'jumped
'over
'the
'lazy
'rhinoceros
'Test 17: Clear linked list. Contains 'jumped' = False
'
C#
using System;
using System.Text;
using System.Collections.Generic;

public class Example
{
    public static void Main()
    {
        // Create the link list.
        string[] words =
            { "the", "fox", "jumped", "over", "the", "dog" };
        LinkedList<string> sentence = new LinkedList<string>(words);
        Display(sentence, "The linked list values:");
        Console.WriteLine("sentence.Contains(\"jumped\") = {0}",
            sentence.Contains("jumped"));

        // Add the word 'today' to the beginning of the linked list.
        sentence.AddFirst("today");
        Display(sentence, "Test 1: Add 'today' to beginning of the list:");

        // Move the first node to be the last node.
        LinkedListNode<string> mark1 = sentence.First;
        sentence.RemoveFirst();
        sentence.AddLast(mark1);
        Display(sentence, "Test 2: Move first node to be last node:");

        // Change the last node be 'yesterday'.
        sentence.RemoveLast();
        sentence.AddLast("yesterday");
        Display(sentence, "Test 3: Change the last node to 'yesterday':");

        // Move the last node to be the first node.
        mark1 = sentence.Last;
        sentence.RemoveLast();
        sentence.AddFirst(mark1);
        Display(sentence, "Test 4: Move last node to be first node:");


        // Indicate, by using parentheisis, the last occurence of 'the'.
        sentence.RemoveFirst();
        LinkedListNode<string> current = sentence.FindLast("the");
        IndicateNode(current, "Test 5: Indicate last occurence of 'the':");

        // Add 'lazy' and 'old' after 'the' (the LinkedListNode named current).
        sentence.AddAfter(current, "old");
        sentence.AddAfter(current, "lazy");
        IndicateNode(current, "Test 6: Add 'lazy' and 'old' after 'the':");

        // Indicate 'fox' node.
        current = sentence.Find("fox");
        IndicateNode(current, "Test 7: Indicate the 'fox' node:");

        // Add 'quick' and 'brown' before 'fox':
        sentence.AddBefore(current, "quick");
        sentence.AddBefore(current, "brown");
        IndicateNode(current, "Test 8: Add 'quick' and 'brown' before 'fox':");

        // Keep a reference to the current node, 'fox',
        // and to the previous node in the list. Indicate the 'dog' node.
        mark1 = current;
        LinkedListNode<string> mark2 = current.Previous;
        current = sentence.Find("dog");
        IndicateNode(current, "Test 9: Indicate the 'dog' node:");

        // The AddBefore method throws an InvalidOperationException
        // if you try to add a node that already belongs to a list.
        Console.WriteLine("Test 10: Throw exception by adding node (fox) already in the list:");
        try
        {
            sentence.AddBefore(current, mark1);
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine("Exception message: {0}", ex.Message);
        }
        Console.WriteLine();

        // Remove the node referred to by mark1, and then add it
        // before the node referred to by current.
        // Indicate the node referred to by current.
        sentence.Remove(mark1);
        sentence.AddBefore(current, mark1);
        IndicateNode(current, "Test 11: Move a referenced node (fox) before the current node (dog):");

        // Remove the node referred to by current.
        sentence.Remove(current);
        IndicateNode(current, "Test 12: Remove current node (dog) and attempt to indicate it:");

        // Add the node after the node referred to by mark2.
        sentence.AddAfter(mark2, current);
        IndicateNode(current, "Test 13: Add node removed in test 11 after a referenced node (brown):");

        // The Remove method finds and removes the
        // first node that that has the specified value.
        sentence.Remove("old");
        Display(sentence, "Test 14: Remove node that has the value 'old':");

        // When the linked list is cast to ICollection(Of String),
        // the Add method adds a node to the end of the list.
        sentence.RemoveLast();
        ICollection<string> icoll = sentence;
        icoll.Add("rhinoceros");
        Display(sentence, "Test 15: Remove last node, cast to ICollection, and add 'rhinoceros':");

        Console.WriteLine("Test 16: Copy the list to an array:");
        // Create an array with the same number of
        // elements as the inked list.
        string[] sArray = new string[sentence.Count];
        sentence.CopyTo(sArray, 0);

        foreach (string s in sArray)
        {
            Console.WriteLine(s);
        }

        // Release all the nodes.
        sentence.Clear();

        Console.WriteLine();
        Console.WriteLine("Test 17: Clear linked list. Contains 'jumped' = {0}",
            sentence.Contains("jumped"));

        Console.ReadLine();
    }

    private static void Display(LinkedList<string> words, string test)
    {
        Console.WriteLine(test);
        foreach (string word in words)
        {
            Console.Write(word + " ");
        }
        Console.WriteLine();
        Console.WriteLine();
    }

    private static void IndicateNode(LinkedListNode<string> node, string test)
    {
        Console.WriteLine(test);
        if (node.List == null)
        {
            Console.WriteLine("Node '{0}' is not in the list.\n",
                node.Value);
            return;
        }

        StringBuilder result = new StringBuilder("(" + node.Value + ")");
        LinkedListNode<string> nodeP = node.Previous;

        while (nodeP != null)
        {
            result.Insert(0, nodeP.Value + " ");
            nodeP = nodeP.Previous;
        }

        node = node.Next;
        while (node != null)
        {
            result.Append(" " + node.Value);
            node = node.Next;
        }

        Console.WriteLine(result);
        Console.WriteLine();
    }
}

//This code example produces the following output:
//
//The linked list values:
//the fox jumped over the dog

//Test 1: Add 'today' to beginning of the list:
//today the fox jumped over the dog

//Test 2: Move first node to be last node:
//the fox jumped over the dog today

//Test 3: Change the last node to 'yesterday':
//the fox jumped over the dog yesterday

//Test 4: Move last node to be first node:
//yesterday the fox jumped over the dog

//Test 5: Indicate last occurence of 'the':
//the fox jumped over (the) dog

//Test 6: Add 'lazy' and 'old' after 'the':
//the fox jumped over (the) lazy old dog

//Test 7: Indicate the 'fox' node:
//the (fox) jumped over the lazy old dog

//Test 8: Add 'quick' and 'brown' before 'fox':
//the quick brown (fox) jumped over the lazy old dog

//Test 9: Indicate the 'dog' node:
//the quick brown fox jumped over the lazy old (dog)

//Test 10: Throw exception by adding node (fox) already in the list:
//Exception message: The LinkedList node belongs a LinkedList.

//Test 11: Move a referenced node (fox) before the current node (dog):
//the quick brown jumped over the lazy old fox (dog)

//Test 12: Remove current node (dog) and attempt to indicate it:
//Node 'dog' is not in the list.

//Test 13: Add node removed in test 11 after a referenced node (brown):
//the quick brown (dog) jumped over the lazy old fox

//Test 14: Remove node that has the value 'old':
//the quick brown dog jumped over the lazy fox

//Test 15: Remove last node, cast to ICollection, and add 'rhinoceros':
//the quick brown dog jumped over the lazy rhinoceros

//Test 16: Copy the list to an array:
//the
//quick
//brown
//dog
//jumped
//over
//the
//lazy
//rhinoceros

//Test 17: Clear linked list. Contains 'jumped' = False
//
Visual C++
#using <System.dll>

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;

void Display(LinkedList<String^>^ words)
{
    for each( String^ word in words )
    {
        Console::Write(word + " ");
    }
    Console::WriteLine();
};

void DisplayNode(LinkedListNode<String^>^ node)
{
    if (node->List == nullptr)
    {
        Console::WriteLine("Node \"{0}\" is not in a list.",
            node->Value);
        return;
    }

    StringBuilder^ result = gcnew StringBuilder("(" + node->Value + ")");
    LinkedListNode<String^>^ nodeP = node->Previous;

    while (nodeP != nullptr)
    {
        result->Insert(0, nodeP->Value + " ");
        nodeP = nodeP->Previous;
    }

    node = node->Next;
    while (node != nullptr)
    {
        result->Append(" " + node->Value);
        node = node->Next;
    }

    Console::WriteLine(result);
};

void main()
{
    array<String^>^ words =
        {"the", "fox", "jumped", "over", "the", "dog"};
    LinkedList<String^>^ sentence =
        gcnew LinkedList<String^>((IEnumerable<String^>^) words);
    Display(sentence);

    Console::WriteLine("sentence->Contains(\"jumped\") = {0}",
        sentence->Contains("jumped"));

    // Add the word "today" to the beginning of the linked list.
    // Remove the new node, and add it to the end of the list.
    sentence->AddFirst("today");
    Display(sentence);

    LinkedListNode<String^>^ mark1 = sentence->First;
    sentence->RemoveFirst();
    sentence->AddLast(mark1);
    Display(sentence);

    sentence->RemoveLast();
    sentence->AddLast("yesterday");
    Display(sentence);

    mark1 = sentence->Last;
    sentence->RemoveLast();
    sentence->AddFirst(mark1);
    Display(sentence);

    sentence->RemoveFirst();

    LinkedListNode<String^>^ current = sentence->FindLast("the");
    DisplayNode(current);

    sentence->AddAfter(current, "old");
    sentence->AddAfter(current, "lazy");
    DisplayNode(current);

    current = sentence->Find("fox");
    DisplayNode(current);

    // Add 'quick' and 'brown' before 'fox':
    sentence->AddBefore(current, "quick");
    sentence->AddBefore(current, "brown");
    DisplayNode(current);

    // Keep a reference to the current node, "fox", and to the
    // previous node in the list. Use the Find method to locate
    // the node containing the value "dog". Show the position.
    mark1 = current;
    LinkedListNode<String^>^ mark2 = current->Previous;
    current = sentence->Find("dog");
    DisplayNode(current);

    // The AddBefore method throws an InvalidOperationException
    // if you try to add a node that already belongs to a list.
    try
    {
        sentence->AddBefore(current, mark1);
    }
    catch(InvalidOperationException^ ex)
    {
        Console::WriteLine("Exception message: {0}", ex->Message);
    }

    // Remove the node referred to by mark1, and add it before
    // the node referred to by current. Show the sentence,
    // highlighting the position of the node referred to by
    // current.
    sentence->Remove(mark1);
    sentence->AddBefore(current, mark1);
    DisplayNode(current);

    // Remove the node referred to by current. If you try to show
    // its position now, the DisplayNode method prints a message.
    // Add the node after the node referred to by mark2, and
    // display the sentence, highlighting current.
    sentence->Remove(current);
    DisplayNode(current);
    sentence->AddAfter(mark2, current);
    DisplayNode(current);

    // The Remove method finds and removes the first node that
    // that has the specified value.
    sentence->Remove("old");
    Display(sentence);

    // When the linked list is cast to ICollection(Of String),
    // the Add method adds a node to the end of the list.
    sentence->RemoveLast();
    ICollection<String^>^ icoll = sentence;
    icoll->Add("rhinoceros");
    Display(sentence);

    // Create an array with the same number of elements as the
    // linked list.
    Console::WriteLine("\nCopy the list to an array.");
    array<String^>^ sArray = gcnew array<String^>(sentence->Count);
    sentence->CopyTo(sArray, 0);

    for each( String^ s in sArray )
    {
        Console::WriteLine(s);
    }

    // Release all the nodes.
    sentence->Clear();
}

//This code example produces the following output:
//
//the fox jumped over the dog
//sentence->Contains("jumped") = True
//today the fox jumped over the dog
//the fox jumped over the dog today
//the fox jumped over the dog yesterday
//yesterday the fox jumped over the dog
//the fox jumped over (the) dog
//the fox jumped over (the) lazy old dog
//the (fox) jumped over the lazy old dog
//the quick brown (fox) jumped over the lazy old dog
//the quick brown fox jumped over the lazy old (dog)
//Exception message: The LinkedList node belongs a LinkedList.
//the quick brown jumped over the lazy old fox (dog)
//Node "dog" is not in a list.
//the quick brown (dog) jumped over the lazy old fox
//the quick brown dog jumped over the lazy fox
//the quick brown dog jumped over the lazy rhinoceros
//
//Copy the list to an array.
//the
//quick
//brown
//dog
//jumped
//over
//the
//lazy
//rhinoceros
Inheritance Hierarchy

System..::.Object
  System.Collections.Generic..::.LinkedList<(Of <(T>)>)
Thread Safety

This type is not thread safe. If the LinkedList<(Of <(T>)>) needs to be accessed by multiple threads, you will need to implement their own synchronization mechanism.

A LinkedList<(Of <(T>)>) can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

Platforms

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360, Zune

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Version Information

.NET Framework

Supported in: 3.5, 3.0, 2.0

.NET Compact Framework

Supported in: 3.5, 2.0

XNA Framework

Supported in: 3.0, 2.0, 1.0
See Also

Reference

Tags :


Page view tracker