2010-01-26 13 views
6

He estado buscando la implementación estándar de una lista doblemente enlazada en C# (de modo que tengo una lista vinculada que puedo repetir al revés) y no puedo encontrar una. Siento que algo tan simple debe tener una implementación que me estoy perdiendo.¿Tiene C# /. Net x.x una implementación de una lista doblemente enlazada (que puede repetirse al revés)?

Si existe, ¿para qué versión de C# /. Net existe?

La iteración inversa en general parece ser algo que no debe hacerse en C#. ¿Está mi mente demasiado pegada en el modo C++/stl o esto es algo que falta en C#?

Conozco LinkedList, pero al no encontrar una manera de iterar al revés asumí que estaba vinculado por separado.

Si LinkedList está doblemente vinculado, ¿cómo se puede iterar hacia atrás (de manera eficiente)?

Respuesta

6

Además de las respuestas dadas aquí, puede escribir un método de extensión a LinkedList<T> para hacer de este un poco más fácil de reutilizar:

public static IEnumerable<T> Backwards(this LinkedList<T> list) 
{ 
    LinkedListNode<T> node= list.Last; 
    while (node != null) 
    { 
     yield return node.Value; 
     node = node.Previous; 
    } 
} 

uso con:

foreach (string x in list.Backwards()) 
{ 
    // ... 
} 
+2

Pequeño error tipográfico: 'LinkedListNode ' debe ser 'LinkedListNode ' – Oliver

+0

@Oliver: gracias, corregido. –

+0

Gracias. Estoy un poco confundido por qué algo como esto ya no está solo en la lib estándar. – Catskul

2

¿Qué tal System.Collections.Generic.LinkedList()

Éstos son los documentos en MSDN:

http://msdn.microsoft.com/en-us/library/he2s3bh7.aspx

Información de la versión
.NET Framework: Compatible con: 3.5, 3.0, 2.0
.NET Compact Framework: Compatible con: 3.5, 2.0
XNA Framework: Compatible con: 3.0, 2.0, 1.0

Dicho esto, estoy con los demás que generalmente es preferible usar una abstracción más alta cuando se trabaja con un marco tan rico.

+0

tengo una necesidad específica de ser capaz de iterar sobre la lista al revés, y tener inserciones baratas + reordenamiento barato. – Catskul

+0

Bien, entonces la primera parte de mi respuesta debería ayudarte. – JohnFx

+0

RTFM no es útil, especialmente porque los documentos no tratan específicamente con la iteración inversa. Si vamos a decirle a todos que trabajen en RTFM, ¿por qué tener Stackoverflow? – Catskul

1

¿Qué tal LinkedList?

+0

¿Cómo se itera eficientemente al revés? – Catskul

+0

while (nodeP! = Null) nodeP = nodeP.Previous; – kenny

10

El siguiente código se repetirá de manera eficiente a través de una LinkedList a la inversa:

 LinkedList<string> list = new LinkedList<string> 
      (new[] {"cat", "dog", "frog", "antelope", "gazelle"}); 
     LinkedListNode<string> item = list.Last; 
     do 
     { 
      Console.WriteLine(item.Value); 
      item = item.Previous; 
     } 
     while (item != null); 
     Console.ReadKey(); 

La clave aquí es que un LinkedList contiene sólo referencia a la primera y última LinkedListNode instancias de la lista. Cada instancia de LinkedListNode contiene una referencia al elemento siguiente y anterior de la lista (o nulo en cada extremo de la lista) y también una propiedad Value. Esto significa que la iteración desde el primer o último LinkedListNode es fácil, pero el acceso aleatorio requiere iteración desde el primero o el último en la lista.

Si necesita hacer una inserción en el camino, utilice LinkedList.AddBefore o AddAfter para insertar un nuevo LinkedListNode.

+0

Eso es lo que estaba buscando. Por alguna razón, tenía la impresión de que la lista .Last devolvería algo del tipo T. Gracias. De alguna manera, usted es la única persona que parece haber entendido el problema o incluso los conceptos detrás de las listas vinculadas en absoluto:/ – Catskul

+0

Un contenedor muy subestimado. Encantado de ayudar. – spender

+1

Esto arrojará una ArgumentNullException si la lista está vacía. Cambiar el ciclo do/while a a (más fácil de leer, IMO) mientras el bucle resolverá el problema - vea mi respuesta para ver un ejemplo. –

Cuestiones relacionadas