Ringikujuline lingitud loend: eelised ja puudused
โก Nutikas kokkuvรตte
Ringlingitud loendid jรคrjestavad sรตlmed nii, et viimane sรตlm liigub tagasi esimese juurde, andes teile pideva, NULL-vaba struktuuri, mis sobib ringjada ajastamiseks, mรคrgirรตngasteks ja igaks tรถรถvooks, mis vajab sujuvat lรคbimist.
Mis on ringikujuline lingitud loend?
Ringjadaga seotud loend on sรตlmede jada, mis on paigutatud nii, et iga sรตlme saab uuesti leida.traciseendale. Iga โsรตlmโ on enesele viitav element, millel on pointerid รผhele vรตi kahele sรตlmele selle vahetus lรคheduses.
Allpool on kujutatud 3 sรตlmega ringikujulist lingitud loendit.
Siin nรคete, et iga sรตlm on uuestitraciseendale kรคttesaadav. รlaltoodud nรคide on ringikujuline รผhekordselt lingitud loend.
Mรคrkus: Lihtsaim ringikujuline lingitud loend on รผksiksรตlm, mille jรคrgmine pointer tracnaaseb iseenda juurde, nagu allpool nรคidatud.
Pรตhi- Operaringloendites
Kolm pรตhilist toimingut ringloendi puhul on:
- sisestamine
- Kustutamine ja
- Lรคbisรตit
- Sisestamine on protsess, mille kรคigus asetatakse sรตlm รผmmarguse lingitud loendi mรครคratud asukohta.
- Kustutamine on lingitud loendist olemasoleva sรตlme eemaldamise protsess. Sรตlme saab tuvastada selle vรครคrtuse esinemise vรตi asukoha jรคrgi.
- Ringlingitud loendi lรคbimine on protsess, mille kรคigus kuvatakse kogu lingitud loendi sisu ja seda uuesti.tractagasi lรคhtesรตlme.
Jรคrgmises osas selgitatakse, kuidas lisamine toimib ja millised on kaks vรตimalikku lisamistรผรผpi ringikujulises รผheselt lingitud loendis.
sisestamine Operamine
Esmalt lood รผhe sรตlme, mille jรคrgmine pointer osutab tagasi iseendale, nagu allpool nรคidatud. Ilma selle seemnesรตlmeta saab esimesest lisamisest loendi esimene sรตlm.
Jรคrgmiseks on kaks vรตimalust.
- Lisamine ringikujuliselt lingitud loendi praegusesse positsiooni. See vastab lisamisele tavalise รผheselt lingitud loendi algusesse vรตi lรตppu โ ringikujuliselt lingitud loendis on algus ja lรตpp sama punkt.
- Sisestamine pรคrast indekseeritud sรตlme. Sรตlm tuleks identifitseerida indeksi numbriga, mis vastab selle elemendi vรครคrtusele.
Ringikujulise lingitud loendi algusesse vรตi lรตppu โ st kohta, kuhu lisati esimene sรตlm โ lisamiseks toimige jรคrgmiselt.
- Peate katkestama olemasoleva iseรผhenduse olemasoleva sรตlmega
- Uue sรตlme jรคrgmine osuti lingib olemasoleva sรตlmega.
- Viimase sรตlme jรคrgmine osuti osutab sisestatud sรตlmele.
MรRKUS: Ringi algust vรตi lรตppu tรคhistava kursori saab รผmber mรครคrata mis tahes sรตlmele. Lรคbiminek naaseb ikkagi samasse sรตlme, nagu selles artiklis hiljem kรคsitletakse.
Punktide (a) iโiii etapid on nรคidatud allpool:
(Olemasolev sรตlm)
Step 1) Katkesta olemasolev link
Step 2) Edasilingi loomine (uuest sรตlmest olemasolevasse sรตlme)
Step 3) Loo silmuslink esimesele sรตlmele
Jรคrgmisena proovite sisestada pรคrast sรตlme.
Nรคiteks sisesta โVALUE2โ pรคrast sรตlme, millel on โVALUE0โ, eeldades, et alguspunktiks on sรตlm, millel on โVALUE0โ.
- Katkesta esimese ja teise sรตlme vaheline รผhendus ning aseta sรตlm, mille vahele jรครคb โVALUE2โ.
- Esimese sรตlme jรคrgmine pointer lingib uue sรตlmega ja uue sรตlme jรคrgmine pointer lingib sellega, mis oli varem teine โโsรตlm.
- รlejรครคnud paigutus jรครคb samaks. Kรตik sรตlmed on รผmber ehitatud.tracendale vรตimelised.
MรRKUS: Kuna tegemist on tsรผklilise paigutusega, on sรตlme lisamise protseduur olenemata valitud positsioonist identne. Tsรผklit sulgev kursor kรคitub nagu iga teine โโloendis olev kursor.
See on nรคidatud allpool:
(รtleme, et sรตlme on ainult kaks. See on triviaalne juhtum)
Step 1) Eemaldage รผhendatud sรตlmede vaheline sisemine lรผli
Step 2) รhendage vasakpoolne sรตlm uue sรตlmega
Step 3) รhendage uus sรตlm parempoolse sรตlmega.
Kustutamine Operamine
Oletame kolme sรตlmega ringikujulist lingitud loendit. Kaks kustutamise juhtu on:
- Praeguse elemendi kustutamine
- Kustutamine pรคrast elementi.
Kustutamine alguses/lรตpus:
- Liikuge viimasest sรตlmest esimesse sรตlme.
- Lรตpust kustutamine nรตuab ainult รผhte lรคbimisetappi, viimasest sรตlmest esimesse sรตlme.
- Kustuta seos viimase ja esimese sรตlme vahel.
- Linkige viimane sรตlm esimese sรตlme jรคrgmise elemendiga.
- Vabastage esimene sรตlm.
(Olemasolev seadistus)
Step 1) Eemalda รผmmargune link
Step 2) Eemaldage seos esimese ja jรคrgmise vahel, linkige viimane sรตlme esimesele jรคrgneva sรตlmega
Step 3) Vabasta / eralda esimene sรตlm
Kustutamine pรคrast sรตlme:
- Liigutakse seni, kuni jรคrgmine sรตlm on kustutatav sรตlm.
- Liikuge jรคrgmisele sรตlmele, asetades kursori eelmisele sรตlmele.
- รhendage eelmine sรตlm praegusele sรตlmele jรคrgneva sรตlmega, kasutades selle jรคrgmist kursorit.
- Vabastage praegune (lingitud) sรตlm.
Step 1) Oletame, et peame kustutama sรตlme vรครคrtusega VALUE1.
Step 2) Eemalda eelmise ja praeguse sรตlme vaheline link ning seejรคrel linki eelmine sรตlm otse sรตlmega, millele osutab praeguse sรตlme jรคrgmine pointer (sรตlm pรคrast VALUE1).
Step 3) Vabastage vรตi eraldage praegune sรตlm.
Ringikujulise lingitud loendi lรคbimine
Ringlingitud loendi lรคbimiseks viimasest pointerist alates kontrollige kรตigepealt, kas viimane pointer on NULL. Kui see ei ole NULL, kontrollige, kas loendis on ainult รผks element. Vastasel juhul liikuge loendis ajutise pointeriga, kuni jรตuate uuesti viimase pointerini, nagu on nรคidatud allolevas animatsioonis.
Ringikujulise lingitud loendi eelised
Mรตned ringikujuliste lingitud loendite eelised on jรคrgmised:
- Koodis ei nรตuta NULL-mรครคrangut. Ringikujuline loend ei osuta kunagi NULL-i osutile, kui see pole tรคielikult eraldatud.
- Ringlingitud loendid on kasulikud loendi lรตpu toimingute jaoks, kuna nende algus ja lรตpp langevad kokku. Algorithms nรคiteks ringjadastamine vรตimaldab jรคrjekorras olevate protsesside vahel sujuvalt liikuda, ilma rippuvate vรตi NULL-viidetega kokku puutumata.
- Ringlingitud loend toetab endiselt kรตiki รผheselt lingitud loendi tavalisi toiminguid. Ringlingitud loend kahekordselt lingitud loend vรตib isegi kaotada vajaduse tรคispika lรคbimise jรคrele elemendi leidmiseks โ halvimal juhul asub sihtmรคrk alguskursori vastas, seega tuleb lรคbida maksimaalselt pool loendist.
Ringliku lingitud loendi puudused
Ringikujulise lingitud loendi kasutamise puudused on jรคrgmised:
- Ringloendid on keerukamad kui รผksikult lingitud loendid.
- RevRingloendi loomine on keerulisem kui รผhe- vรตi kahekordselt lingitud loendi tรผhistamine.
- Kui tsรผkli lรตpetamist ei kรคsitleta hoolikalt, vรตib lรคbimiskood siseneda lรตpmatusse tsรผklisse.
- Loendi lรตppu on raskem leida ja รตigeid tsรผkli juhtimistingimusi kirjutada.
- Alguses lisamine nรตuab kogu loendi lรคbimist, et jรตuda viimase sรตlmeni (rakenduse seisukohast).
รksiklingitud loend ringikujulise lingitud loendina
Soovitame teil lugeda ja rakendada allolevat C-koodi. See illustreerib ringja รผheselt lingitud loendiga seotud pointeri aritmeetikat.
#include<stdio.h> #include<stdlib.h> struct node { int item; struct node *next; }; struct node* addToEmpty(struct node*,int); struct node *insertCurrent(struct node *, int); struct node *insertAfter(struct node *, int, int); struct node *removeAfter(struct node *, int); struct node *removeCurrent(struct node *); void peek(struct node *); int main() { ...
Koodi selgitus:
- Esimesed kaks koodirida on vajalikud kaasatud pรคisefailid.
- Jรคrgmises osas defineeritakse iga enesele viitava sรตlme struktuur. See sisaldab vรครคrtust ja sama tรผรผpi pointerit kui struktuur.
- Iga struktuuri eksemplar lingib teiste sama tรผรผpi struktuuriobjektidega.
- Funktsioonide prototรผรผbid on erinevad:
- Elemendi lisamine tรผhja lingitud loendisse
- Sisestamine juures praegu osutas ringikujulise lingitud loendi asukoht.
- Sisestamine pรคrast konkreetset indekseeritud vรครคrtus lingitud loendis.
- Eemaldamine/kustutamine pรคrast konkreetset indekseeritud vรครคrtus lingitud loendis.
- Ringikujulise lingitud loendi praegu suunatud positsiooni eemaldamine
- Viimane funktsioon prindib iga elemendi ringikujulise lรคbimise kaudu lingitud loendi mis tahes olekus.
int main() { struct node *last = NULL; last = insertCurrent(last,4); last = removeAfter(last, 4); peek(last); return 0; } struct node* addToEmpty(struct node*last, int data) { struct node *temp = (struct node *)malloc(sizeof( struct node)); temp->item = data; last = temp; last->next = last; return last; } struct node *insertCurrent(struct node *last, int data)
Koodi selgitus:
- Koodi โaddToEmptyโ jaoks eraldage malloc() funktsiooni abil tรผhi sรตlm.
- Asetage sissetulevad andmed ajutisse sรตlme.
- Mรครคra ajutine sรตlm viimaseks ja sea selle jรคrgmine pointer iseendale, nii et รผksik sรตlm osutab tagasi iseendale.
- Tagasta viimane pointer tagasi main() / rakenduse konteksti.
struct node *insertCurrent(struct node *last, int data) { if(last == NULL) { return addToEmpty(last, data); } struct node *temp = (struct node *)malloc(sizeof( struct node)); temp -> item = data; temp->next = last->next; last->next = temp; return last; } struct node *insertAfter(struct node *last, int data, int item) { struct node *temp = last->next, *prev = temp, *newnode =NULL; …
Koodi selgitus
- Kui loend on tรผhi, anna see รผle funktsioonile addToEmpty() ja tagasta kontroll.
- Loo ajutine sรตlm, mis asetatakse praeguse sรตlme jรคrele.
- รhenda kursorid รผlaltoodud diagrammil nรคidatud viisil.
- Tagasta viimane pointer, mis vastab eelmises funktsioonis kasutatud mustrile.
... struct node *insertAfter(struct node *last, int data, int item) { struct node *temp = last->next, *prev = temp, *newnode =NULL; if (last == NULL) { return addToEmpty(last, item); } do { prev = temp; temp = temp->next; } while (temp->next != last && temp->item != data ); if(temp->item != data) { printf("Element not found. Please try again"); ...
Koodi selgitus:
- Kui loend on tรผhi, ignoreerige otsinguvรตtit, lisage praegune รผksus loendi ainsaks sรตlmeks ja tagastage juhtelement.
- Igas do-while tsรผkli iteratsioonis hoiab eelmine pointer viimati lรคbitud tulemust.
- Alles siis toimub jรคrgmine lรคbimisetapp.
- โdo-whileโ funktsioon lรตpeb, kui sihtandmed leitakse vรตi kui โtempโ jรตuab uuesti viimase pointerini. Jรคrgnev koodiplokk otsustab, mida leitud objektiga peale hakata.
...
if(temp->item != data)
{
printf("Element not found. Please try again");
return last;
}
else
{
newnode = (struct node *)malloc(sizeof(struct node));
newnode->item = item;
prev->next = newnode;
newnode->next = temp;
}
return last;
}
struct node *removeCurrent(struct node *last)
...
Koodi selgitus:
- Kui kogu nimekiri on lรคbi kรคidud, aga soovitud elementi ei leita, kuvatakse teade โElementi ei leitudโ ja kontroll tagastatakse helistajale.
- Kui sihtsรตlm leitakse, eraldage vรครคrtusele uus sรตlm.
- on siin eelmise sรตlme uue sรตlmega ja lingi uue sรตlme jรคrgmine pointer muutujaga temp (lรคbimismuutuja).
- See paigutab uue elemendi ringikujulises lingitud loendis kohe sihtsรตlme jรคrele. Seejรคrel naaseb juhtimine kutsujale.
struct node *removeCurrent(struct node *last) { if(last == NULL) { printf("Element Not Found"); return NULL; } struct node *temp = last->next; last->next = temp->next; free(temp); return last; } struct node *removeAfter(struct node *last, int data)
Koodi selgitus
- Viimase (praeguse) sรตlme eemaldamiseks kontrollige kรตigepealt, kas loend on tรผhi. Kui on, siis ei saa รผhtegi elementi eemaldada.
- Muutuja temp liigutab รผhe lรผli edasi.
- Seo viimane pointer esimesele sรตlmele jรคrgneva sรตlmega.
- Vabastage ajutine pointer, et vabastada linkimata sรตlm.
struct node *removeAfter(struct node *last,int data) { struct node *temp = NULL,*prev = NULL; if (last == NULL) { printf("Linked list empty. Cannot remove any element\n"); return NULL; } temp = last->next; prev = temp; do { prev = temp; temp = temp->next; } while (temp->next != last && temp->item != data ); if(temp->item != data) { printf("Element not found"); ...
Koodi selgitus
- Nagu eelmise eemaldamisfunktsiooni puhul, kontrollige kรตigepealt, kas loend on tรผhi. Kui on, siis ei saa รผhtegi elementi eemaldada.
- Kaks osutid kustutatava elemendi leidmiseks on mรครคratud kindlad positsioonid.
- Osutajad nihutatakse รผksteise jรคrel edasi (eelmised rajad, ajutine).
- Lรคbimine jรคtkub seni, kuni sihtelement leitakse vรตi jรคrgmine pointer jรตuab uuesti viimase sรตlmeni.
if(temp->item != data) { printf("Element not found"); return last; } else { prev->next = temp->next; free(temp); } return last; } void peek(struct node * last) { struct node *temp = last; if (last == NULL) { return;
Programmi selgitus
- Kui kogu lingitud loend lรคbitakse sihtmรคrki leidmata, kuvatakse teade โElementi ei leitudโ.
- Vastasel juhul elemendi linkimine katkestatakse ja see vabastatakse 3. ja 4. etapis.
- Eelmine pointer on lingitud sรตlmega, millele osutab temp'i jรคrgmine pointer (sรตlm pรคrast kustutatavat).
- Seejรคrel vabastatakse temperatuuri indikaator.
... void peek(struct node * last) { struct node *temp = last; if (last == NULL) { return; } if(last -> next == last) { printf("%d-", temp->item); } while (temp != last) { printf("%d-", temp->item); temp = temp->next; } }
Koodi selgitus
- Peek-lรคbimine pole vรตimalik, kui sรตlmi pole รผhtegi โ kasutaja peab kรตigepealt sรตlme eraldama vรตi lisama.
- Kui sรตlmi on ainult รผks, pole lรคbimist vaja โ sรตlme sisu trรผkitakse otse ja while-tsรผklit ei kรคivitata.
- Kui sรตlmi on rohkem kui รผks, prindib temp kรตik elemendid kuni viimase elemendini.
- Viimase elemendini jรตudes tsรผkkel lรตpeb ja funktsioon tagastab juhtimise funktsioonile main().
Ringliku lingitud loendi rakendused
- Ringplaanimise rakendamine sรผsteemiprotsessides ja ringgraafiku rakendamine kiires graafikas.
- Token-ringi ajastamine arvutivรตrkudes.
- Kasutatakse kuvamisรผksustes, nรคiteks digitaalsetes mรผรผgikohtades, mis vajavad pidevat andmete lรคbimist.





























