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.

  • ๐Ÿ“š Mรครคratlus: Igal sรตlmel on vรครคrtus ja jรคrgmine pointer ning viimase sรตlme jรคrgmine pointer lingib tagasi esimesega, luues suletud tsรผkli.
  • ๐Ÿ“Œ tuum Operatused: Lisamine, kustutamine ja lรคbimine keerlevad kรตik รผhe vรตi kahe jรคrgmise pointeri vรคrskendamise รผmber, sรคilitades samal ajal tsรผkli.
  • ๐Ÿ› ๏ธ C-i rakendamine: Struktuuripรตhised sรตlmed, millel on malloc-toega lisamised ja vabatoega kustutused, hรตlmavad nii praeguse positsiooni kui ka pรคrast sรตlme asuvaid juhtumeid.
  • โœ… Plussid: Puuduvad NULL-i viited, sujuvad otsast algusesse รผleminekud ja kahekordselt ringikujulised variandid, mis poole vรตrra vรคhendavad halvima juhtumi otsinguid.
  • โš ๏ธ Puudused: Keerukam tsรผklikontroll, suurem keerukus kui รผksikult lingitud loenditel ja lรตpmatud tsรผklid, kui terminatsioon on valesti kirjutatud.
  • ๐ŸŽฏ Rakendused: Protsessori ringjaotusega ajastamine, mรคrgirรตngasvรตrgud, ringpuhvrid, meediaesitusloendid ja pideva kuvamisega รผksused.

Ringikujuline lingitud loend

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.

Ringikujuline lingitud loend

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.

Ringikujuline lingitud loend

Pรตhi- Operaringloendites

Kolm pรตhilist toimingut ringloendi puhul on:

  1. sisestamine
  2. Kustutamine ja
  3. 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.

sisestamine Operamine

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:

sisestamine Operamine

(Olemasolev sรตlm)

sisestamine Operamine

Step 1) Katkesta olemasolev link

sisestamine Operamine

Step 2) Edasilingi loomine (uuest sรตlmest olemasolevasse sรตlme)

sisestamine Operamine

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:

sisestamine Operamine

(รœtleme, et sรตlme on ainult kaks. See on triviaalne juhtum)

sisestamine Operamine

Step 1) Eemaldage รผhendatud sรตlmede vaheline sisemine lรผli

sisestamine Operamine

Step 2) รœhendage vasakpoolne sรตlm uue sรตlmega

sisestamine Operamine

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:

  1. Liikuge viimasest sรตlmest esimesse sรตlme.
  2. Lรตpust kustutamine nรตuab ainult รผhte lรคbimisetappi, viimasest sรตlmest esimesse sรตlme.
  3. Kustuta seos viimase ja esimese sรตlme vahel.
  4. Linkige viimane sรตlm esimese sรตlme jรคrgmise elemendiga.
  5. Vabastage esimene sรตlm.

Kustutamine Operamine

(Olemasolev seadistus)

Kustutamine Operamine

Step 1) Eemalda รผmmargune link

Kustutamine Operamine

Step 2) Eemaldage seos esimese ja jรคrgmise vahel, linkige viimane sรตlme esimesele jรคrgneva sรตlmega

Kustutamine Operamine

Step 3) Vabasta / eralda esimene sรตlm

Kustutamine pรคrast sรตlme:

  1. Liigutakse seni, kuni jรคrgmine sรตlm on kustutatav sรตlm.
  2. Liikuge jรคrgmisele sรตlmele, asetades kursori eelmisele sรตlmele.
  3. รœhendage eelmine sรตlm praegusele sรตlmele jรคrgneva sรตlmega, kasutades selle jรคrgmist kursorit.
  4. Vabastage praegune (lingitud) sรตlm.

Kustutamine Operamine

Step 1) Oletame, et peame kustutama sรตlme vรครคrtusega VALUE1.

Kustutamine Operamine

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).

Kustutamine Operamine

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 lรคbimine

Ringikujulise lingitud loendi eelised

Mรตned ringikujuliste lingitud loendite eelised on jรคrgmised:

  1. Koodis ei nรตuta NULL-mรครคrangut. Ringikujuline loend ei osuta kunagi NULL-i osutile, kui see pole tรคielikult eraldatud.
  2. 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.
  3. 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:

  1. Ringloendid on keerukamad kui รผksikult lingitud loendid.
  2. RevRingloendi loomine on keerulisem kui รผhe- vรตi kahekordselt lingitud loendi tรผhistamine.
  3. Kui tsรผkli lรตpetamist ei kรคsitleta hoolikalt, vรตib lรคbimiskood siseneda lรตpmatusse tsรผklisse.
  4. Loendi lรตppu on raskem leida ja รตigeid tsรผkli juhtimistingimusi kirjutada.
  5. 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()
{
...

รœksiklingitud loend

Koodi selgitus:

  1. Esimesed kaks koodirida on vajalikud kaasatud pรคisefailid.
  2. Jรคrgmises osas defineeritakse iga enesele viitava sรตlme struktuur. See sisaldab vรครคrtust ja sama tรผรผpi pointerit kui struktuur.
  3. Iga struktuuri eksemplar lingib teiste sama tรผรผpi struktuuriobjektidega.
  4. Funktsioonide prototรผรผbid on erinevad:
    1. Elemendi lisamine tรผhja lingitud loendisse
    2. Sisestamine juures praegu osutas ringikujulise lingitud loendi asukoht.
    3. Sisestamine pรคrast konkreetset indekseeritud vรครคrtus lingitud loendis.
    4. Eemaldamine/kustutamine pรคrast konkreetset indekseeritud vรครคrtus lingitud loendis.
    5. Ringikujulise lingitud loendi praegu suunatud positsiooni eemaldamine
  5. 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)

รœksiklingitud loend

Koodi selgitus:

  1. Koodi โ€žaddToEmptyโ€ jaoks eraldage malloc() funktsiooni abil tรผhi sรตlm.
  2. Asetage sissetulevad andmed ajutisse sรตlme.
  3. Mรครคra ajutine sรตlm viimaseks ja sea selle jรคrgmine pointer iseendale, nii et รผksik sรตlm osutab tagasi iseendale.
  4. 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;
&#8230;

รœksiklingitud loend

Koodi selgitus

  1. Kui loend on tรผhi, anna see รผle funktsioonile addToEmpty() ja tagasta kontroll.
  2. Loo ajutine sรตlm, mis asetatakse praeguse sรตlme jรคrele.
  3. รœhenda kursorid รผlaltoodud diagrammil nรคidatud viisil.
  4. 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");
...

รœksiklingitud loend

Koodi selgitus:

  1. Kui loend on tรผhi, ignoreerige otsinguvรตtit, lisage praegune รผksus loendi ainsaks sรตlmeks ja tagastage juhtelement.
  2. Igas do-while tsรผkli iteratsioonis hoiab eelmine pointer viimati lรคbitud tulemust.
  3. Alles siis toimub jรคrgmine lรคbimisetapp.
  4. โ€ž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)
...

รœksiklingitud loend

Koodi selgitus:

  1. Kui kogu nimekiri on lรคbi kรคidud, aga soovitud elementi ei leita, kuvatakse teade โ€žElementi ei leitudโ€ ja kontroll tagastatakse helistajale.
  2. Kui sihtsรตlm leitakse, eraldage vรครคrtusele uus sรตlm.
  3. on siin eelmise sรตlme uue sรตlmega ja lingi uue sรตlme jรคrgmine pointer muutujaga temp (lรคbimismuutuja).
  4. 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)

รœksiklingitud loend

Koodi selgitus

  1. Viimase (praeguse) sรตlme eemaldamiseks kontrollige kรตigepealt, kas loend on tรผhi. Kui on, siis ei saa รผhtegi elementi eemaldada.
  2. Muutuja temp liigutab รผhe lรผli edasi.
  3. Seo viimane pointer esimesele sรตlmele jรคrgneva sรตlmega.
  4. 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");
...

รœksiklingitud loend

Koodi selgitus

  1. Nagu eelmise eemaldamisfunktsiooni puhul, kontrollige kรตigepealt, kas loend on tรผhi. Kui on, siis ei saa รผhtegi elementi eemaldada.
  2. Kaks osutid kustutatava elemendi leidmiseks on mรครคratud kindlad positsioonid.
  3. Osutajad nihutatakse รผksteise jรคrel edasi (eelmised rajad, ajutine).
  4. 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;

รœksiklingitud loend

Programmi selgitus

  1. Kui kogu lingitud loend lรคbitakse sihtmรคrki leidmata, kuvatakse teade โ€žElementi ei leitudโ€.
  2. Vastasel juhul elemendi linkimine katkestatakse ja see vabastatakse 3. ja 4. etapis.
  3. Eelmine pointer on lingitud sรตlmega, millele osutab temp'i jรคrgmine pointer (sรตlm pรคrast kustutatavat).
  4. 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;
    }
}

รœksiklingitud loend

Koodi selgitus

  1. Peek-lรคbimine pole vรตimalik, kui sรตlmi pole รผhtegi โ€” kasutaja peab kรตigepealt sรตlme eraldama vรตi lisama.
  2. Kui sรตlmi on ainult รผks, pole lรคbimist vaja โ€” sรตlme sisu trรผkitakse otse ja while-tsรผklit ei kรคivitata.
  3. Kui sรตlmi on rohkem kui รผks, prindib temp kรตik elemendid kuni viimase elemendini.
  4. 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.

KKK

Tehisintellekti assistendid, nรคiteks GitHub Copiloti ja ChatGPT tugisรตlmede struktuurid, malloc-pรตhised inserterid ja tsรผklikindlad lรคbimistsรผklid. Arendajad kontrollivad genereeritud koodi enne tootmisandmestruktuuridega รผhendamist รตigete lรตpetamistingimuste ja mรคlu puhastamise osas.

Masinรตppe torujuhtmed kasutavad รผmmarguste lingitud loenditele ehitatud รผmmargusi puhvreid voogedastusandmete jooksvate akende hoidmiseks, korduspuhvri nรคidiseid tugevdusรตppe agentidele ja tsรผklilisi jรคrjekordi tootja-tarbija tรถรถtajatele, kes toidavad treeningpartiisid.

รœhekordselt lingitud loend lรตpeb NULL-kursoriga, samas kui ringlingitud loendi viimane sรตlm osutab tagasi esimesele sรตlmele. See suletud tsรผkkel eemaldab NULL-kontrollid loendi lรตpus ja toetab pidevat, รผmberpรถรถratavat lรคbimist รผhes tsรผklis.

Ringjalt kahekordselt lingitud loendil on sรตlme kohta kaks pointerit โ€“ jรคrgmine ja eelmine โ€“ ning mรตlemad otsad teevad tsรผkliga tagasipรถรถrdumise รผksteise juurde. See struktuur toetab kahesuunalist lรคbimist ja halvima juhtumi otsinguid maksimaalselt poole loendi pikkuse ulatuses.

Floydi kilpkonna ja jรคnese algoritm kasutab kahte erineva kiirusega liikuvat pointerit. Kui need kohtuvad, on tegemist tsรผkliga. See tรถรถtab O(n) aja ja O(1) lisaruumiga ning on tsรผkli tuvastamise standardne intervjuulahendus.

Ringikujulise lingitud loendi praegusesse positsiooni sisestamine vรตi kustutamine toimub funktsioonis O(1). OperaKonkreetsele vรครคrtusele vรตi indeksile suunatud toimingud tรคituvad O(n)-is, kuna sihtsรตlme leidmiseks tuleb loend lรคbida.

OperaTing-sรผsteemi ajastajad kasutavad neid protsessori ringajastumiseks, mรคrgirรตngasvรตrgud edastavad juhtimist jaamade vahel, meediapleierid tsรผkliliselt esitusloendeid lรคbivad ja manussรผsteemid kasutavad andurivoogude jaoks ringpuhvreid, mida toetavad ringloendid.

Levinud vigade hulka kuuluvad mรตlema lรตpp-punkti pointeri vรคrskendamise unustamine pรคrast sisestamist vรตi kustutamist, lรตpetamistingimuse tรคitmata jรคtmine ja ...ping igaveseks, vabastades sรตlme ilma naabreid uuesti linkimata ja lekkides mรคlu, kui loend visatakse รคra.

Vรตta see postitus kokku jรคrgmiselt: