A tömb adatszerkezet kiváló, ha elÅ‘re tudjuk, hogy mennyi elemre van szükségünk. Abban az esetben viszont, ha nem tudjuk elÅ‘re, hogy mennyi elemünk lesz, akkor nehezen tudjuk bÅ‘vÃteni a késÅ‘bbiekben.
Lényegében a bÅ‘vÃtés csak úgy lehetséges, hogy létrehozunk egy újabb tömböt, aminek a mérete a hozzáadandó elemek számával meg van növelve. Az új tömbbe átmásoljuk a meglévÅ‘ tömb elemeit, majd az új tömbhöz hozzáadjuk az új elemeket. Végezetül pedig töröljük az eredeti tömböt.
Az algoritmus leÃrásból kiolvasható, hogy ez nem éppen ideális, mivel a sebességre igen negatÃv hatással van a másolás. Továbbá a másolás folyamán egy rövid idÅ‘re duplázódik a programunk memóriahasználata.
Egy sokkal jobb megoldás lehet nagy mennyiségű, elÅ‘re nem ismert számú adat tárolására a láncolt lista szerkezet. Ennek lényege, hogy van egy láncszem tÃpusunk, amely tartalmazza a tárolni kÃvánt elemi tÃpust és egy referenciát a következÅ‘ elemre. Ha a referencia a következÅ‘ elemre nem létezik, akkor a lánc végén vagyunk.
Ezt a megoldást hÃvjuk egyszeresen láncolt listának. Ennek hátránya, hogy az elemeken csak sorban tudunk végighaladni az elejétÅ‘l a végéig. Viszont, ha kiegészÃtjük a láncszem tÃpusunkat egy referenciával, ami az elÅ‘zÅ‘ láncelemre mutat, akkor kétszeresen láncolt listát kapunk, amiben szabadon mozoghatunk elÅ‘re és hátra is. Valamint a lánc ebben az esetben bÅ‘vÃthetÅ‘ az elején és a végén is, mÃg az egyszeresen láncolt listánk csak a végén bÅ‘vÃthetÅ‘.
Ezen adatszerkezet elÅ‘nye, hogy ugyanazzal a sebességgel a végtelenségig bÅ‘vÃthetÅ‘ a lánc. Hátránya viszont az, hogy csak szekvenciális olvasást tud gyorsan. Egy adott elem indexhez csak úgy tudunk eljutni a láncban, hogy az elejétÅ‘l elkezdjük olvasni az elemeket és megállunk a kÃvánt elemnél.
A .NET láncolt lista implementációja nem meglepő módon a LinkedList osztálynevet kapta. Az alábbi fontosabb metódusokkal és tulajdonságokkal rendelkezik:
LinkedListNode<T> First { get; }
Referencia a lánc első elemére.
LinkedListNode<T> Last { get; }
Referencia a lánc utolsó elemére.
LinkedListNode<T> AddAfter(LinkedListNode node, T value)
A lánc bÅ‘vÃtése az elsÅ‘ paraméter által meghatározott elem után. A második paraméter az értéket határozza meg. A metódus visszatérési értéke az újonnan létrejött láncelem.
LinkedListNode<T> AddBefore(LinkedListNode node, T value)
A lánc bÅ‘vÃtése az elsÅ‘ paraméter által meghatározott elem elÅ‘tt. A második paraméter az értéket határozza meg. A metódus visszatérési értéke az újonnan létrejött láncelem.
LinkedListNode<T> Find(T value)
Kikeresi a paraméter által meghatározott értékhez tartozó első láncelemet.
LinkedListNode<T> FindLast(T value)
Kikeresi a paraméter által meghatározott értékhez tartozó utolsó láncelemet.
LinkedListNode<T> AddFirst(T value)
Lánc bÅ‘vÃtése az elején. A meghatározott érték által létrejövÅ‘ láncelem lesz a lánc elsÅ‘ eleme. A metódus visszatérési értéke az újonnan létrejött láncelem.
LinkedListNode<T> AddLast(T value)
Lánc bÅ‘vÃtése a végén. A meghatározott érték által létrejövÅ‘ láncelem lesz a lánc utolsó eleme. A metódus visszatérési értéke az újonnan létrejött láncelem.
void RemoveFirst()
Lánc elsÅ‘ elemének eltávolÃtása. A metódus hÃvása után a második láncelem lesz az új elsÅ‘.
void RemoveLast()
Lánc utolsó elemének eltávolÃtása. A metódus hÃvása után az utolsó elÅ‘tti láncelem lesz az új utolsó.
A láncolt lista szerkezethez tartozó belső láncelem, LinkedListNode osztály tulajdonságai:
LinkedListNode<T> Next { get; }
A következő láncelemre mutató referencia
LinkedListNode<T> Previous { get; }
Az előző láncelemre mutató referencia
T Value { get; set; }
A láncelem által tárolt érték lekérdezése vagy beállÃtása.
A következő mintaprogram a láncolt lista használatát mutatja be:
using System;
using System.Collections.Generic;
namespace PeldaLancolt
{
class Program
{
static void Main(string[] args)
{
var lista = new LinkedList<string>();
//jobbról bÅ‘vÃtés
lista.AddLast("egy");
lista.AddLast("példa");
lista.AddLast("program");
lista.AddLast("lenne");
//balról bÅ‘vÃtés
lista.AddFirst("Ez");
Console.WriteLine("Lánc elemek száma: {0}", lista.Count);
Console.WriteLine("Lánc tartalma előre: ");
//a foreach automatikusan a value elemet szedi ki
foreach (var elem in lista)
{
Console.Write("{0} ", elem);
}
Console.WriteLine("\nLánc tartalma vissza: ");
var vissza = lista.Last;
while (vissza != null)
{
Console.Write("{0} ", vissza.Value);
vissza = vissza.Previous;
}
Console.ReadKey();
}
}
}
A program kimenete:
Lánc elemek száma: 5
Lánc tartalma elore:
Ez egy példa program lenne
Lánc tartalma vissza:
lenne program példa egy Ez