Kuten taulukot, jotka otettiin käyttöön tämän opetusohjelman osassa 3, linkitetyt luettelot ovat perustietorakenne, johon monimutkaisemmat tietorakenteet voivat perustua. Toisin kuin alkioiden sarja, a linkitetty luettelo on solmujen sarja, jossa kukin solmu on linkitetty sarjan edelliseen ja seuraavaan solmuun. Muista, että a solmu on objekti, joka on luotu itseviittausluokasta, ja a itseviittausluokka on vähintään yksi kenttä, jonka viittaustyyppi on luokan nimi. Linkitetyn luettelon solmut linkitetään solmuviitteen avulla. Tässä on esimerkki:
luokka Työntekijä {private int empno; yksityinen merkkijono nimi; yksityinen kaksinkertainen palkka; julkinen työntekijä seuraavaksi; // Muut jäsenet. }
Tässä esimerkissä Työntekijä
on itseviittausluokka, koska se Seuraava
kentällä on tyyppi Työntekijä
. Tämä kenttä on esimerkki a linkkikenttä koska se voi tallentaa viitteen luokan toiseen esineeseen - tässä tapauksessa toiseen Työntekijä
esine.
Tämä opetusohjelma esittelee Java-ohjelmoinnin yksitellen linkitettyjen luetteloiden sisäpiirit. Opit yksittäisen linkitetyn luettelon luomisen, solmujen lisäämisen yksitellen linkitettyyn luetteloon, solmujen poistamisen yksitellen linkitetystä luettelosta, yhdistämisen yksittäisesti linkitetyn luettelon toiseen yksin linkitettyyn luetteloon ja kääntämisen yksittäin linkitetyn luettelon kääntämiseksi. Tutkimme myös algoritmeja, joita yleisimmin käytetään yksin linkitettyjen luetteloiden lajittelussa, ja lopuksi esimerkillä, joka osoittaa lisäyslajittelualgoritmin.
lataa Hanki koodi Lataa tämän artikkelin kolme esimerkkisovellusta. Luonut Jeff Friesen JavaWorldille.Mikä on yksittäisesti linkitetty luettelo?
A linkitetty luettelo on linkitetty luettelo solmuista, joissa jokaisella solmulla on yksi linkkikenttä. Tässä tietorakenteessa viitemuuttuja sisältää viittauksen ensimmäiseen (tai ylimpään) solmuun; kukin solmu (paitsi viimeinen tai alin solmu) linkittää seuraavaan; ja viimeisen solmun linkkikenttä sisältää nollaviitteen, joka merkitsee luettelon loppua. Vaikka viitemuuttuja on yleisesti nimetty alkuun
, voit valita haluamasi nimen.
Kuvassa 1 on yksi linkitetty luettelo, jossa on kolme solmua.

Alla on pseudokoodi yksittäisesti linkitetylle luettelolle.
ILMOITA LUOKASolmu ILMOITA STRING-nimi ILMOITA Solmu seuraava LOPETA ILMOITA ILMOITA Solmu alkuun = NULL
Solmu
on itseviittausluokka, jolla on a nimi
tietokenttä ja a Seuraava
linkkikenttä. alkuun
on tyypin viitemuuttuja Solmu
siinä on viittaus ensimmäiseen Solmu
objekti linkitetyssä luettelossa. Koska luetteloa ei ole vielä olemassa, alkuun
alkuperäinen arvo on TYHJÄ
.
Yksin linkitetyn luettelon luominen Java-sovelluksessa
Voit luoda yhden linkitetyn luettelon liittämällä siihen yhden Solmu
esine. Seuraava pseudokoodi luo a Solmu
objektin, määrittää sen viitteen alkuun
, alustaa tietokentän ja määrittää TYHJÄ
linkkikenttään:
top = UUSI Solmu top.name = "A" top.next = NULL
Kuvassa 2 on esitetty ensimmäinen pseudokoodista syntyvä yksittäisesti linkitetty luettelo.

Tämän operaation aikakompleksi on O (1) - vakio. Muista, että O (1) lausutaan "Big Oh of 1". (Katso osasta 1 muistutus siitä, kuinka ajan ja tilan monimutkaisuusmittauksia käytetään tietorakenteiden arvioimiseen.)
Lisätään solmut yksittäisesti linkitettyyn luetteloon
Solmun lisääminen yksin linkitettyyn luetteloon on jonkin verran monimutkaisempaa kuin yksin linkitetyn luettelon luominen, koska on otettava huomioon kolme tapausta:
- Lisäys ennen ensimmäistä solmua.
- Lisäys viimeisen solmun jälkeen.
- Lisäys kahden solmun väliin.
Lisäys ennen ensimmäistä solmua
Uusi solmu lisätään ennen ensimmäistä solmua osoittamalla ylimmän solmun viite uuden solmun linkkikenttään ja osoittamalla uuden solmun viite alkuun
muuttuja. Tämän toiminnan osoittaa seuraava pseudokoodi:
ILMOITA Solmun temp temp = UUSI Solmun temp.nimi = "B" temp.seuraava = ylh. Ylin = lämpötila
Tuloksena olevatSolmu
luettelo näkyy kuvassa 3.

Tämän operaation aikakompleksi on O (1).
Lisäys viimeisen solmun jälkeen
Uusi solmu lisätään viimeisen solmun jälkeen osoittamalla tyhjä uuden solmun linkkikenttään, kulkemalla yksi linkitetty luettelo viimeisen solmun löytämiseksi ja osoittamalla uuden solmun viittaus viimeisen solmun linkkikenttään, kuten seuraava pseudokoodi osoittaa:
temp = NEW Solmu temp.name = "C" temp.next = NULL DECLARE Solmu temp2 temp2 = top // Oletetaan, että top (ja temp2) eivät ole NULL // edellisen pseudokoodin takia. WHILE temp2.next NE NULL temp2 = temp2.next END WHILE // temp2 viittaa nyt viimeiseen solmuun. temp2.seuraava = lämpötila
Kuva 4 paljastaa luettelon lisäämisen jälkeen Solmu
C jälkeen Solmu
A.

Tällä operaatiolla on O-ajan monimutkaisuus (n)--lineaarinen. Sen aikakompleksisuutta voitaisiin parantaa O: ksi (1) ylläpitämällä viittaus viimeiseen solmuun. Siinä tapauksessa ei ole tarpeen etsiä viimeistä solmua.
Lisäys kahden solmun väliin
Solmun lisääminen kahden solmun väliin on monimutkaisin tapaus. Voit lisätä uuden solmun kahden solmun väliin kulkemalla luetteloa etsimään uuden solmun edelle tuleva solmu, määrittämällä löydetyn solmun linkkikentän viite uuden solmun linkkikenttään ja osoittamalla uuden solmun viittaus löydetyn solmun linkkiin ala. Seuraava näennäiskoodi osoittaa nämä tehtävät:
temp = UUSI Solmu temp.name = "D" temp2 = alkuun // Oletetaan, että uusi luotu solmu lisää solmun // A perään ja että solmu A on olemassa. Todellisessa maailmassa ei ole // takuuta siitä, että jokin solmu on olemassa, joten meidän on tarkistettava // temp2, joka sisältää NULL sekä WHILE-silmukan otsikossa // että sen jälkeen, kun WHILE-silmukka on valmis. WHILE temp2.name NE "A" temp2 = temp2.next END WHILE // temp2 viittaa nyt solmuun A. temp.next = temp2.next temp2.next = temp
Kuvassa 5 on luettelo lisäyksen jälkeen Solmu
D välillä Solmu
s A ja C.

Tällä operaatiolla on O-ajan monimutkaisuus (n).
Solmujen poistaminen linkitetystä luettelosta
Solmun poistaminen yksin linkitetystä luettelosta on myös jonkin verran monimutkaisempaa kuin yksin linkitetyn luettelon luominen. Harkittavia tapauksia on kuitenkin vain kaksi:
- Ensimmäisen solmun poisto.
- Poistetaan kaikki solmut paitsi ensimmäinen solmu.
Ensimmäisen solmun poisto
Ensimmäisen solmun poistaminen tarkoittaa linkin osoittamista ensimmäisen solmun linkkikentässä muuttujalle, joka viittaa ensimmäiseen solmuun, mutta vain silloin, kun on olemassa ensimmäinen solmu:
JOS alkuun EI NULL SITTU top = top.sext; // Viittaus toiseen solmuun (tai NULL, kun solmuja on vain yksi). LOPPU JOS
Kuva 6 esittää luettelon näkymiä ennen ja jälkeen, joista ensimmäinen Solmu
on poistettu. Solmu B
katoaa ja Solmu
A: sta tulee ensimmäinen Solmu
.

Tämän operaation aikakompleksi on O (1).
Poistetaan kaikki solmut paitsi ensimmäinen solmu
Minkä tahansa solmun poistaminen, mutta ensimmäinen solmu sisältää poistettavan solmun edeltävän solmun paikantamisen ja viittauksen osoittamisen poistettavan solmun linkkikentässä edellisen solmun linkkikenttään. Harkitse seuraavaa pseudokoodia:
JOS ylhäältä NE TYHJÄ Sitten temp = alkuun KUN Temp.nimi EI "A" temp = temp.seuraava LOPETTAA, kun taas // Oletetaan, että lämpötila viittaa Solmu A. temp.next = temp.next.next // Solmua D ei enää ole. LOPPU JOS
Kuvassa 7 esitetään ennen ja jälkeen luettelonäkymät, joissa välituote Solmu
poistetaan. Solmu
D katoaa.

Tällä operaatiolla on O-ajan monimutkaisuus (n).
Esimerkki 1: Luo, lisää ja poista linkitetty luettelo
Olen luonut Java-sovelluksen nimeltä SLLDemo
joka osoittaa, kuinka luoda, lisätä ja poistaa solmuja linkitettyyn luetteloon. Listaus 1 esittää tämän sovelluksen lähdekoodin.
Listaus 1. Java-sovellusten esittely yksin linkitetyille luetteloille (SSLDemo.java, versio 1)
julkinen lopullinen luokka SLLDemo {yksityinen staattinen luokka Solmu {Merkkijonon nimi; Seuraava solmu; } public static void main (Merkkijono [] argumentit) {Solmu ylhäällä = tyhjä; // 1. Yksittäisesti linkitettyä luetteloa ei ole olemassa. top = uusi solmu (); top.name = "A"; top.next = null; dump ("tapaus 1", yläosa); // 2. Yksin linkitetty luettelo on olemassa ja solmu on lisättävä // ennen ensimmäistä solmua. Solmun lämpötila; temp = uusi solmu (); temp.nimi = "B"; temp.seuraava = yläosa; yläosa = lämpötila; dump ("tapaus 2", yläosa); // 3. Yksin linkitetty luettelo on olemassa ja solmu on lisättävä // viimeisen solmun jälkeen. temp = uusi solmu (); temp.nimi = "C"; temp.next = null; Solmu temp2; temp2 = yläosa; while (temp2.next! = null) temp2 = temp2.next; temp2.seuraava = temp; dump ("tapaus 3", yläosa); // 4. Yksin linkitetty luettelo on olemassa ja solmu on lisättävä // kahden solmun väliin. temp = uusi solmu (); temp.nimi = "D"; temp2 = yläosa; while (temp2.nimi. on yhtä suuri ("A") == false) temp2 = temp2.seuraava; temp.next = temp2.next; temp2.seuraava = temp; dump ("tapaus 4", yläosa); // 5. Poista ensimmäinen solmu. alkuun = ylh. seuraava; dump ("Ensimmäisen solmun poiston jälkeen", ylhäältä); // 5.1 Palauta solmu B. temp = new Node (); temp.nimi = "B"; temp.seuraava = yläosa; yläosa = lämpötila; // 6. Poista kaikki solmut paitsi ensimmäinen solmu. lämpötila = yläosa; while (temp.nimi. on yhtä suuri ("A") == false) temp = temp.seuraava; temp.next = temp.next.next; dump ("D-solmun poiston jälkeen", ylhäältä); } private static void dump (String msg, Node topNode) {System.out.print (msg + ""); while (topNode! = null) {System.out.print (topNode.name + ""); topNode = topNode.next; } System.out.println (); }}
Koosta Listaus 1 seuraavasti:
javac SLLDemo.java
Suorita tuloksena oleva sovellus seuraavasti:
java SLLDemo
Ota huomioon seuraava tulos:
Tapaus 1 A Tapaus 2 B A Tapaus 3 B A C Tapaus 4 B A D C ensimmäisen solmupoiston jälkeen A D C D-solmun poiston jälkeen B A C
Yhdistettyjen linkitettyjen luetteloiden yhdistäminen
Saatat joutua joskus liittämään yhteen linkitetyn luettelon toiseen yksin linkitettyyn luetteloon. Oletetaan esimerkiksi, että sinulla on luettelo sanoista, jotka alkavat kirjaimista A - M ja toinen luettelo sanoista, jotka alkavat kirjaimista N - Z, ja haluat yhdistää nämä luettelot yhdeksi luetteloksi. Seuraava pseudokoodi kuvaa algoritmia yksittäisen linkitetyn luettelon liittämiseen toiseen:
DECLARE-solmu top1 = NULL DECLARE-solmu top2 = NULL // Oletetaan koodi, joka luo top1-viitatun yksittäisesti linkitetyn luettelon. // Oletetaan koodi, joka luo top2-viitatun yksittäisesti linkitetyn luettelon. // Yhdistä top2-viitattu luettelo top1-viitattuun luetteloon. JOS top1 EQ NULL top1 = top2 END END IF // Etsi viimeinen solmu top1-viitteellisestä luettelosta. ILMOITA Solmun lämpötila = top1 KUN Lämpötila seuraava EI NULL temp = Lämpötila seuraava END WHILE // Yhdistä top2 to top1. temp.sext = top2 END
Triviaalissa tapauksessa ei ole alkuun 1
-viitattu luettelo, ja niin alkuun 1
on osoitettu alkuun2
arvo, joka olisi TYHJÄ
jos ei olisi alkuun2
-viitattu luettelo.
Tällä operaatiolla on O (1): n aikakompleksi triviaalissa tapauksessa ja O: n aikakompleksi (n) muuten. Jos kuitenkin ylläpidät viittausta viimeiseen solmuun, ei tarvitse etsiä luetteloa tälle solmulle. ajan monimutkaisuus muuttuu arvoksi O (1).
Yhden linkitetyn luettelon kääntäminen
Toinen hyödyllinen operaatio linkitetyllä luettelolla on käänteinen, joka kääntää luettelon linkit päinvastaiseksi, jotta voit siirtyä sen solmuista vastakkaiseen suuntaan. Seuraava pseudokoodi kääntää alkuun 1
-viitatun luettelon linkit:
ILMOITA Solmu p = top1 // Alkuperäisen linkitetyn luettelon alkuun. ILMOITA Solmu q = NULL // Käänteisen yksittäisesti linkitetyn luettelon yläreuna. DECLARE Node r // Väliaikainen solmu -viitemuuttuja. WHOLE p NE NULL // Jokaiselle solmulle alkuperäisessä yksitellen linkitetyssä luettelossa ... r = q // Tallenna tulevan seuraajan solmun viite. q = p // Viittaus tulevaan edeltäjään Solmu. p = p.seuraava // Seuraava seuraava solmu alkuperäisessä yksittäisesti linkitetyssä luettelossa. q.next = r // Linkitä tuleva edeltäjän solmu tulevaan seuraajaan. END WHILE top1 = q // Tee ensimmäinen1-viite ensin Solmu päinvastaisessa linkitetyssä luettelossa. LOPPU
Tällä operaatiolla on O-ajan monimutkaisuus (n).
Esimerkki # 2: Yhdistetyn linkitetyn luettelon yhdistäminen ja kääntäminen
Olen luonut toisen version SLLDemo
Java-sovellus, joka osoittaa ketjutuksen ja kääntämisen. Listaus 2 esittää tämän sovelluksen lähdekoodin.