linked list data structure c with illustration
Detaljna studija povezanog popisa na C ++.
Povezani popis linearna je dinamička struktura podataka za pohranu podataka. Već smo vidjeli nizove u našim prethodnim temama o osnovnom C ++-u. Također znamo da su nizovi linearna struktura podataka koja pohranjuje stavke podataka na susjedna mjesta.
Za razliku od nizova, povezani popis ne pohranjuje podatke na susjedna memorijska mjesta.
Povezani popis sastoji se od predmeta nazvanih 'Čvorovi' koji sadrže dva dijela. Prvi dio pohranjuje stvarne podatke, a drugi dio ima pokazivač koji pokazuje na sljedeći čvor. Ova se struktura obično naziva 'Popis pojedinačno povezanih'.
=> Ovdje pogledajte najbolje tutorijale za C ++.
Što ćete naučiti:
Povezani popis u C ++
Pojedinačno povezani popis detaljno ćemo pogledati u ovom vodiču.
Sljedeći dijagram prikazuje strukturu pojedinačno povezanog popisa.
Kao što je gore prikazano, prvi čvor povezanog popisa naziva se 'glava', dok se zadnji čvor naziva 'rep'. Kao što vidimo, posljednji čvor povezanog popisa imat će sljedeći pokazivač kao nulu jer neće imati ukazanu memorijsku adresu.
Budući da svaki čvor ima pokazivač na sljedeći čvor, stavke podataka na povezanom popisu ne moraju biti pohranjene na susjednim mjestima. Čvorovi se mogu raspršiti u memoriji. Čvorovima možemo pristupiti bilo kada, jer će svaki čvor imati adresu sljedećeg čvora.
Možemo dodati podatkovne stavke na povezani popis, kao i lako ih brisati. Stoga je moguće dinamički povećati ili smanjiti povezani popis. Ne postoji gornje ograničenje broja stavki podataka na povezanom popisu. Dakle, sve dok je memorija dostupna, možemo dodati onoliko podataka na povezani popis.
Osim jednostavnog umetanja i brisanja, povezani popis također ne troši prostor u memoriji jer ne moramo prethodno navesti koliko stavki trebamo na povezanom popisu. Jedini prostor koji zauzima povezani popis je za spremanje pokazivača na sljedeći čvor koji dodaje malo više troškova.
Zatim ćemo razgovarati o raznim operacijama koje se mogu izvesti na povezanom popisu.
Operacije
Baš kao i ostale strukture podataka, možemo izvoditi razne operacije i za povezani popis. Ali za razliku od nizova, u kojima elementu možemo pristupiti izravno koristeći indeks, čak i ako je negdje između, ne možemo učiniti isti nasumični pristup s povezanim popisom.
Da bismo pristupili bilo kojem čvoru, moramo preći povezani popis od početka i tek tada možemo pristupiti željenom čvoru. Stoga se slučajni pristup podacima s povezanog popisa pokazuje skupim.
Možemo izvoditi razne operacije na povezanom popisu kako je navedeno u nastavku:
# 1) Umetanje
Operacija umetanja povezanog popisa dodaje stavku na povezani popis. Iako možda zvuči jednostavno, s obzirom na strukturu povezanog popisa, znamo da svaki put kad se stavka podataka doda na povezani popis, moramo promijeniti sljedeće pokazivače na prethodni i sljedeći čvor nove stavke koju smo umetnuli.
Druga stvar koju moramo uzeti u obzir je mjesto na kojemu treba dodati novu stavku podataka.
Na povezanom su popisu tri mjesta na koja se može dodati stavka podataka.
# 1) Na početku povezanog popisa
Povezani popis prikazan je ispod 2-> 4-> 6-> 8-> 10. Ako želimo dodati novi čvor 1, kao prvi čvor popisa, tada će glava koja pokazuje na čvor 2 sada voditi na 1, a sljedeći pokazivač čvora 1 imat će memorijsku adresu čvora 2 kao što je prikazano u nastavku lik.
Tako novi povezani popis postaje 1-> 2-> 4-> 6-> 8-> 10.
# 2) Nakon datog čvora
Ovdje se daje čvor i mi moramo dodati novi čvor nakon datog čvora. Na dolje povezanom popisu a-> b-> c-> d -> e, ako želimo dodati čvor f nakon čvora c, tada će povezani popis izgledati kako slijedi:
Tako u gornjem dijagramu provjeravamo je li dati čvor prisutan. Ako je prisutan, stvaramo novi čvor f. Zatim usmjerimo sljedeći pokazivač čvora c kako bi ukazao na novi čvor f. Sljedeći pokazivač čvora f sada pokazuje na čvor d.
# 3) Na kraju povezanog popisa
U trećem slučaju dodajemo novi čvor na kraju povezanog popisa. Uzmimo u obzir da imamo isti povezani popis a-> b-> c-> d-> e i trebamo dodati čvor f na kraj popisa. Povezani popis izgledat će kao što je prikazano u nastavku nakon dodavanja čvora.
Tako stvaramo novi čvor f. Tada je repni pokazivač koji pokazuje na nulu usmjeren na f, a sljedeći pokazivač na čvor f usmjeren je na nulu. Sve tri vrste funkcija umetanja implementirali smo u donji program C ++.
U C ++-u možemo povezati popis deklarirati kao strukturu ili kao klasu. Deklariranje povezanog popisa kao strukture tradicionalna je deklaracija u stilu C. Povezani popis kao klasa koristi se u modernom C ++-u, uglavnom dok se koristi standardna biblioteka predložaka.
U sljedećem programu koristili smo strukturu za deklariranje i stvaranje povezanog popisa. Članovi će imati podatke i pokazivač na sljedeći element.
#include using namespace std; // A linked list node struct Node { int data; struct Node *next; }; //insert a new node in front of the list void push(struct Node** head, int node_data) { /* 1. create and allocate node */ struct Node* newNode = new Node; /* 2. assign data to node */ newNode->data = node_data; /* 3. set next of new node as head */ newNode->next = (*head); /* 4. move the head to point to the new node */ (*head) = newNode; } //insert new node after a given node void insertAfter(struct Node* prev_node, int node_data) { /*1. check if the given prev_node is NULL */ if (prev_node == NULL) { coutnext = prev_node->next; /* 5. move the next of prev_node as new_node */ prev_node->next = newNode; } /* insert new node at the end of the linked list */ void append(struct Node** head, int node_data) { /* 1. create and allocate node */ struct Node* newNode = new Node; struct Node *last = *head; /* used in step 5*/ /* 2. assign data to the node */ newNode->data = node_data; /* 3. set next pointer of new node to null as its the last node*/ newNode->next = NULL; /* 4. if list is empty, new node becomes first node */ if (*head == NULL) { *head = newNode; return; } /* 5. Else traverse till the last node */ while (last->next != NULL) last = last->next; /* 6. Change the next of last node */ last->next = newNode; return; } // display linked list contents void displayList(struct Node *node) { //traverse the list to display each node while (node != NULL) { coutnext; } if(node== NULL) cout Izlaz:
Konačni povezani popis:
30–> 20–> 50–> 10–> 40–> null
Dalje, u Java implementiramo operaciju umetanja povezanog popisa. U jeziku Java, povezani je popis implementiran kao klasa. Program u nastavku logički je sličan programu C ++, jedina je razlika što za povezani popis koristimo klasu.
class LinkedList { Node head; // head of list //linked list node declaration class Node { int data; Node next; Node(int d) {data = d; next = null; } } /* Insert a new node at the front of the list */ public void push(int new_data) { //allocate and assign data to the node Node newNode = new Node(new_data); //new node becomes head of linked list newNode.next = head; //head points to new node head = newNode; } // Given a node,prev_node insert node after prev_node public void insertAfter(Node prev_node, int new_data) { //check if prev_node is null. if (prev_node == null) { System.out.println('The given node is required and cannot be null'); return; } //allocate node and assign data to it Node newNode = new Node(new_data); //next of new Node is next of prev_node newNode.next = prev_node.next; //prev_node->next is the new node. prev_node.next = newNode; } //inserts a new node at the end of the list public void append(intnew_data) { //allocate the node and assign data Node newNode = new Node(new_data); //if linked list is empty, then new node will be the head if (head == null) { head = new Node(new_data); return; } //set next of new node to null as this is the last node newNode.next = null; // if not the head node traverse the list and add it to the last Node last = head; while (last.next != null) last = last.next; //next of last becomes new node last.next = newNode; return; } //display contents of linked list public void displayList() { Node pnode = head; while (pnode != null) { System.out.print(pnode.data+'-->'); pnode = pnode.next; } if(pnode == null) System.out.print('null'); } } //Main class to call linked list class functions and construct a linked list class Main{ public static void main(String[] args) { /* create an empty list */ LinkedList lList = new LinkedList(); // Insert 40. lList.append(40); // Insert 20 at the beginning. lList.push(20); // Insert 10 at the beginning. lList.push(10); // Insert 50 at the end. lList.append(50); // Insert 30, after 20. lList.insertAfter(lList.head.next, 30); System.out.println('
Final linked list: '); lList. displayList (); } }
Izlaz:
Konačni povezani popis:
10–> 20–> 30–> 40–> 50–> null
U oba gornja programa, C ++, kao i Java, imamo odvojene funkcije za dodavanje čvora ispred popisa, kraja popisa i između popisa danih u čvoru. Na kraju ispisujemo sadržaj popisa stvorenog pomoću sve tri metode.
# 2) Brisanje
Poput umetanja, brisanje čvora s povezanog popisa također uključuje različite položaje s kojih se čvor može izbrisati. Možemo izbrisati prvi čvor, posljednji čvor ili slučajni kth čvor s povezanog popisa. Nakon brisanja trebamo na odgovarajući način prilagoditi sljedeći pokazivač i ostale pokazivače na povezanom popisu kako bi povezani popis ostao netaknut.
U sljedećoj implementaciji C ++-a dali smo dvije metode brisanja, tj. Brisanje prvog čvora na popisu i brisanje posljednjeg čvora na popisu. Prvo kreiramo popis dodavanjem čvorova u glavu. Zatim prikazujemo sadržaj popisa nakon umetanja i svakog brisanja.
#include using namespace std; /* Link list node */ struct Node { int data; struct Node* next; }; //delete first node in the linked list Node* deleteFirstNode(struct Node* head) { if (head == NULL) return NULL; // Move the head pointer to the next node Node* tempNode = head; head = head->next; delete tempNode; return head; } //delete last node from linked list Node* removeLastNode(struct Node* head) { if (head == NULL) return NULL; if (head->next == NULL) { delete head; return NULL; } // first find second last node Node* second_last = head; while (second_last->next->next != NULL) second_last = second_last->next; // Delete the last node delete (second_last->next); // set next of second_last to null second_last->next = NULL; return head; } // create linked list by adding nodes at head void push(struct Node** head, int new_data) { struct Node* newNode = new Node; newNode->data = new_data; newNode->next = (*head); (*head) = newNode; } // main function int main() { /* Start with the empty list */ Node* head = NULL; // create linked list push(&head, 2); push(&head, 4); push(&head, 6); push(&head, 8); push(&head, 10); Node* temp; cout<<'Linked list created ' Izlaz:
Stvoren je povezani popis
10–> 8–> 6–> 4–> 2–
> NIŠTA
Povezani popis nakon brisanja glavnog čvora
8–> 6–> 4–> 2–
> NIŠTA
Povezani popis nakon brisanja zadnjeg čvora
8–> 6–> 4–> NULL
Sljedeća je Java implementacija za brisanje čvorova s povezanog popisa. Logika implementacije je ista kao i u programu C ++. Jedina je razlika što je povezani popis deklariran kao klasa.
class Main { // Linked list node / static class Node { int data; Node next; }; // delete first node of linked list static Node deleteFirstNode(Node head) { if (head == null) return null; // Move the head pointer to the next node Node temp = head; head = head.next; return head; } // Delete the last node in linked list static Node deleteLastNode(Node head) { if (head == null) return null; if (head.next == null) { return null; } // search for second last node Node second_last = head; while (second_last.next.next != null) second_last = second_last.next; // set next of second last to null second_last.next = null; return head; } // Add nodes to the head and create linked list static Node push(Node head, int new_data) { Node newNode = new Node(); newNode.data = new_data; newNode.next = (head); (head) = newNode; return head; } //main function public static void main(String args[]) { // Start with the empty list / Node head = null; //create linked list head = push(head, 1); head = push(head, 3); head = push(head, 5); head = push(head, 7); head = push(head, 9); Node temp; System.out.println('Linked list created :'); for (temp = head; temp != null; temp = temp.next) System.out.print(temp.data + '-->'); if(temp == null) System.out.println('null'); head = deleteFirstNode(head); System.out.println('Linked list after deleting head node :'); for (temp = head; temp != null; temp = temp.next) System.out.print(temp.data + '-->'); if(temp == null) System.out.println('null'); head = deleteLastNode(head); System.out.println('Linked list after deleting last node :'); for (temp = head; temp != null; temp = temp.next) System.out.print(temp.data + '-->'); if(temp == null) System.out.println('null'); } }
Izlaz:
Stvoren je povezani popis:
9–> 7–> 5–> 3–> 1–
> null
softver za najbolje performanse za Windows 10
Povezani popis nakon brisanja glavnog čvora:
7–> 5–> 3–> 1–
> null
Povezani popis nakon brisanja zadnjeg čvora:
7–> 5–> 3–> null
Prebrojite broj čvorova
Operacija brojanja broja čvorova može se izvesti tijekom obilaženja povezanog popisa. Već smo vidjeli u gornjoj implementaciji da kad god moramo umetnuti / izbrisati čvor ili prikazati sadržaj povezanog popisa, moramo preći povezani popis od početka.
Zadržavanje brojača i njegovo povećavanje dok prelazimo svaki čvor dat će nam broj broja čvorova prisutnih na povezanom popisu. Ostavit ćemo ovaj program čitateljima na provođenju.
Nizovi i povezani popisi
Nakon što smo vidjeli rad i provedbu povezanog popisa, usporedimo kako su nizovi i povezani popisi pošteni u usporedbi jedni s drugima.
Nizovi Povezani popisi Nizovi imaju fiksnu veličinu Veličina povezanog popisa je dinamična Umetanje novog elementa je skupo Umetanje / brisanje je lakše Dopušten je slučajan pristup Nasumični pristup nije moguć Elementi su na susjednom mjestu Elementi se nalaze nesusjedno Za sljedeći pokazivač nije potreban dodatni prostor Za sljedeći pokazivač potreban je dodatni memorijski prostor
Prijave
Kako se nizovi i povezani popisi koriste za spremanje predmeta i predstavljaju linearne strukture podataka, obje se strukture mogu koristiti na slične načine za većinu aplikacija.
Neke od aplikacija za povezane popise su sljedeće:
- Povezani popis može se koristiti za implementaciju stogova i redova.
- Povezani popis također se može koristiti za implementaciju grafova kad god moramo grafikone predstavljati kao popise susjedstva.
- Matematički polinom može se pohraniti kao povezani popis.
- U slučaju tehnike raspršivanja, segmenti korišteni u raspršivanju implementiraju se pomoću povezanih popisa.
- Kad god program zahtijeva dinamičku dodjelu memorije, možemo se poslužiti povezanim popisom jer povezani popisi djeluju učinkovitije u ovom slučaju.
Zaključak
Povezani popisi su podatkovne strukture koje se koriste za linearno pohranjivanje podataka, ali nestalnih mjesta. Povezani popis zbirka je čvorova koji sadrže podatkovni dio i sljedeći pokazivač koji sadrži memorijsku adresu sljedećeg elementa na popisu.
Posljednji element na popisu ima sljedeći pokazivač postavljen na NULL, čime označava kraj popisa. Prvi element popisa naziva se Glava. Povezani popis podržava razne operacije poput umetanja, brisanja, obrtanja itd. U slučaju dinamičke dodjele memorije, povezani su popisi prednost nad nizovima.
Povezani popisi skupi su što se tiče njihovog obilaženja, jer ne možemo nasumično pristupiti elementima poput nizova. Međutim, operacije umetanja i brisanja jeftinije su u usporedbi s nizovima.
Sve o linearno povezanim popisima naučili smo u ovom vodiču. Povezani popisi također mogu biti kružni ili dvostruki. Te ćemo popise detaljno pregledati u našim nadolazećim vodičima.
=> Ovdje potražite kompletnu seriju C ++ treninga.
Preporučena literatura
- Struktura podataka kružnog povezanog popisa na C ++ s ilustracijom
- Dvostruko povezana struktura podataka popisa na C ++ s ilustracijom
- Struktura podataka u redu čekanja u C ++ s ilustracijom
- Složite strukturu podataka u C ++ s ilustracijom
- Struktura podataka prioritetnog reda u C ++ s ilustracijom
- 15 najboljih besplatnih alata za rudarenje podataka: Najopsežniji popis
- 15 najboljih ETL alata u 2021. godini (potpuni ažurirani popis)
- Uvod u strukture podataka na C ++