А повезана листа је врста линеарне динамичке структуре података коју користимо за складиштење елемената података. Низови су такође врста линеарне структуре података где се ставке података чувају у непрекидним меморијским блоковима.
За разлику од низова, повезана листа не мора да складишти елементе података у суседним меморијским регионима или блоковима.
А повезана листа састоји се од елемената познатих као 'чворови' који су подељени на два дела. Прва компонента је део где чувамо стварне податке, а друга је део где чувамо показивач на следећи чвор. Ова врста структуре је позната као ' једноструко повезана листа .'
Повезана листа у Ц++
Овај водич ће детаљно проћи кроз појединачно повезану листу.
Структура појединачно повезане листе је илустрована на дијаграму испод
- Као што смо видели у горњем делу, први чвор повезане листе је познат као 'глава', док се последњи чвор назива 'реп.' Зато што у последњем чвору није наведена меморијска адреса, коначни чвор повезане листе ће имати нулти следећи показивач.
- Пошто сваки чвор укључује показивач на следећи чвор, елементи података у повезаној листи не морају да се задржавају на суседним локацијама. Чворови могу бити распршени по меморији. Пошто сваки чвор има адресу оног после њега, можемо приступити чворовима кад год желимо.
- Можемо брзо додати и уклонити ставке података са повезане листе. Као резултат тога, повезана листа може се динамички повећавати или скупљати. Повезана листа нема максималну количину ставки података коју може да садржи. Као резултат тога, можемо додати онолико ставки података колико желимо на повезану листу све док је доступна РАМ меморија.
- Пошто не морамо унапред да наведемо колико нам је ставки потребно у повезаној листи, повезана листа штеди меморијски простор поред тога што је једноставна за уметање и брисање. Једини простор који користи повезана листа је складиштење показивача на следећи чвор, што додатно повећава трошкове.
Након тога, прећи ћемо на различите операције које се могу извршити на повезаној листи.
1) Уметање
Повезана листа се проширује акцијом додавања на њу. Иако би изгледало једноставно, с обзиром на структуру повезане листе, знамо да сваки пут када се дода ставка података, морамо променити следеће показиваче претходног и следећег чвора нове ставке коју смо додали.
Где ће нова ставка података бити уметнута је други аспект о коме треба размислити.
Постоје три места где се ставка података може додати на повезану листу.
а. Почевши од повезане листе
стринг јава садржи
Испод је повезана листа бројева 2->4->6->8->10. Глава која показује на чвор 2 ће сада показивати на чвор 1, а следећи показивач чвора 1 ће имати меморијску адресу чвора 2, као што је приказано на илустрацији испод, ако додамо нови чвор 1 као први чвор на листи .
Као резултат, нова повезана листа је 1->2->4->6->8->10.
б. Након датог Чвора
У овом случају, добијамо чвор и морамо додати нови чвор иза њега. Повезана листа ће изгледати овако ако се чвор ф дода повезаној листи а->б->ц->д->е после чвора ц:
Стога проверавамо да ли је наведени чвор присутан на дијаграму изнад. Ако је присутан, креира се нови чвор ф. Након тога, усмеравамо следећи показивач чвора ц на потпуно нови чвор ф. Следећи показивач чвора ф сада показује на чвор д.
ц. Последња ставка повезане листе
У трећем случају, нови чвор се додаје на крај повезане листе. Узмите у обзир повезану листу испод: а->б->ц->д->е, са додатком чвора ф на крају. Након додавања чвора, повезана листа ће изгледати овако.
Као резултат тога, конструишемо нови чвор ф. Показивач репа који води до нуле се тада показује на ф, а следећи показивач чвора ф на нулу. У програмском језику испод, генерисали смо све три врсте функција уметања.
Повезана листа може бити декларисана као структура или као класа у Ц++. Повезана листа декларисана као структура је класична изјава у Ц стилу. Повезана листа се користи као класа у модерном Ц++, углавном када се користи стандардна библиотека шаблона.
Структура је коришћена у следећој апликацији за декларисање и генерисање повезане листе. Његови чланови ће бити подаци и показивач на следећи елемент.
Ц++ програм:
#include using namespace std; struct Node { int data; struct Node *next; }; void push ( struct Node** head, int nodeData ) { struct Node* newNode1 = new Node; newNode1 -> data = nodeData; newNode1 -> next = (*head); (*head) = newNode1; } void insertAfter ( struct Node* prevNode, int nodeData ) { if ( prevNode == NULL ) { cout <data = nodedata; newnode1 -> next = prevNode -> next; prevNode -> next = newNode1; } void append ( struct Node** head, int nodeData ) { struct Node* newNode1 = new Node; struct Node *last = *head; newNode1 -> data = nodeData; newNode1 -> next = NULL; if ( *head == NULL ) { *head = newNode1; return; } while ( last -> next != NULL ) last = last -> next; last -> next = newNode1; return; } void displayList ( struct Node *node ) { while ( node != NULL ) { cout <data <'; node="node" -> next; } if ( node== NULL) cout<next, 55 ); cout << 'final linked list: ' endl; displaylist (head); return 0; } < pre> <p> <strong>Output:</strong> </p> <pre> Final linked list: 35-->25-->55-->15-->45-->null </pre> <h3>2) Deletion</h3> <p>Similar to insertion, deleting a node from a linked list requires many points from which the node might be eliminated. We can remove the linked list's first, last, or kth node at random. We must correctly update the next pointer and all other linked list pointers in order to maintain the linked list after deletion.</p> <p>In the following C++ implementation, we have two deletion methods: deleting the list's initial node and deleting the list's last node. We begin by adding nodes to the head of the list. The list's contents are then shown following each addition and deletion.</p> <p> <strong>C++ Program:</strong> </p> <pre> #include using namespace std; struct Node { int data; struct Node* next; }; Node* deletingFirstNode ( struct Node* head ) { if ( head == NULL ) return NULL; Node* tempNode = head; head = head -> next; delete tempNode; return head; } Node* removingLastNode ( struct Node* head ) { if ( head == NULL ) return NULL; if ( head -> next == NULL ) { delete head; return NULL; } Node* secondLast = head; while ( secondLast -> next -> next != NULL ) secondLast = secondLast->next; delete ( secondLast -> next ); secondLast -> next = NULL; return head; } void push ( struct Node** head, int newData ) { struct Node* newNode1 = new Node; newNode1 -> data = newData; newNode1 -> next = ( *head ); ( *head ) = newNode1; } int main() { Node* head = NULL; push ( &head, 25 ); push ( &head, 45 ); push ( &head, 65); push ( &head, 85 ); push ( &head, 95 ); Node* temp; cout << 'Linked list created ' < next ) cout <data <'; if ( temp="=" null ) cout << 'null' endl; head="deletingFirstNode" (head); 'linked list after deleting node' < next <data cout<<'null'<<endl; last data 'null'; return 0; } pre> <p> <strong>Output:</strong> </p> <pre> Linked list created 95-->85-->65-->45-->25-->NULL Linked list after deleting head node 85-->65-->45-->25-->NULL Linked list after deleting last node 85-->65-->45-->NULL </pre> <h3>Node Count</h3> <p>While traversing the linked list, the process of counting the number of nodes can be performed. In the preceding approach, we saw that if we needed to insert/delete a node or display the contents of the linked list, we had to traverse the linked list from the beginning.</p> <p>Setting a counter and incrementing as well as we traverse each node will provide us the number of nodes in the linked list.</p> <h3>Differences between Array and Linked list:</h3> <table class="table"> <tr> <th>Array</th> <th>Linked list</th> </tr> <tr> <td>Arrays have a defined size.</td> <td>The size of the linked list is variable.</td> </tr> <tr> <td>Inserting a new element is difficult.</td> <td>Insertion and deletion are simpler.</td> </tr> <tr> <td>Access is permitted at random.</td> <td>No random access is possible.</td> </tr> <tr> <td>Elements are in relatively close or contiguous.</td> <td>The elements are not contiguous.</td> </tr> <tr> <td>No additional room is required for the following pointer.</td> <td>The following pointer requires additional memory.</td> </tr> </table> <h3>Functionality</h3> <p>Since linked lists and arrays are both linear data structures that hold objects, they can be utilised in similar ways for the majority of applications.</p> <p>The following are some examples of linked list applications:</p> <ul> <li>Stacks and queues can be implemented using linked lists.</li> <li>When we need to express graphs as adjacency lists, we can use a linked list to implement them.</li> <li>We can also use a linked list to contain a mathematical polynomial.</li> <li>In the case of hashing, linked lists are employed to implement the buckets.</li> <li>When a programme requires dynamic memory allocation, we can utilize a linked list because linked lists are more efficient in this instance.</li> </ul> <h2>Conclusion</h2> <p>Linked lists are data structures used to hold data elements in a linear but non-contiguous form. A linked list is made up of nodes with two components each. The first component is made up of data, while the second half has a pointer that stores the memory address of the following member of the list.</p> <p>As a sign that the linked list has ended, the last item in the list has its next pointer set to NULL. The Head is the first item on the list. The linked list allows for a variety of actions such as insertion, deletion, traversal, and so on. Linked lists are favoured over arrays for dynamic memory allocation.</p> <p>Linked lists are hard to print or traverse because we can't access the elements randomly like arrays. When compared to arrays, insertion-deletion procedures are less expensive.</p> <p>In this tutorial, we learned everything there is to know about linear linked lists. Linked lists can also be doubly linked or circular. In our forthcoming tutorials, we will go through these lists in detail.</p> <hr></data></pre></next,></data></data>
2) Брисање
Слично уметању, брисање чвора са повезане листе захтева много тачака из којих се чвор може елиминисати. Можемо насумично уклонити први, последњи или к-ти чвор повезане листе. Морамо исправно ажурирати следећи показивач и све друге показиваче повезане листе како бисмо одржали повезану листу након брисања.
У следећој Ц++ имплементацији, имамо две методе брисања: брисање почетног чвора листе и брисање последњег чвора листе. Почињемо додавањем чворова на врх листе. Садржај листе се затим приказује након сваког додавања и брисања.
Ц++ програм:
#include using namespace std; struct Node { int data; struct Node* next; }; Node* deletingFirstNode ( struct Node* head ) { if ( head == NULL ) return NULL; Node* tempNode = head; head = head -> next; delete tempNode; return head; } Node* removingLastNode ( struct Node* head ) { if ( head == NULL ) return NULL; if ( head -> next == NULL ) { delete head; return NULL; } Node* secondLast = head; while ( secondLast -> next -> next != NULL ) secondLast = secondLast->next; delete ( secondLast -> next ); secondLast -> next = NULL; return head; } void push ( struct Node** head, int newData ) { struct Node* newNode1 = new Node; newNode1 -> data = newData; newNode1 -> next = ( *head ); ( *head ) = newNode1; } int main() { Node* head = NULL; push ( &head, 25 ); push ( &head, 45 ); push ( &head, 65); push ( &head, 85 ); push ( &head, 95 ); Node* temp; cout << 'Linked list created ' < next ) cout <data <\'; if ( temp="=" null ) cout << \'null\' endl; head="deletingFirstNode" (head); \'linked list after deleting node\' < next <data cout<<\'null\'<<endl; last data \'null\'; return 0; } pre> <p> <strong>Output:</strong> </p> <pre> Linked list created 95-->85-->65-->45-->25-->NULL Linked list after deleting head node 85-->65-->45-->25-->NULL Linked list after deleting last node 85-->65-->45-->NULL </pre> <h3>Node Count</h3> <p>While traversing the linked list, the process of counting the number of nodes can be performed. In the preceding approach, we saw that if we needed to insert/delete a node or display the contents of the linked list, we had to traverse the linked list from the beginning.</p> <p>Setting a counter and incrementing as well as we traverse each node will provide us the number of nodes in the linked list.</p> <h3>Differences between Array and Linked list:</h3> <table class="table"> <tr> <th>Array</th> <th>Linked list</th> </tr> <tr> <td>Arrays have a defined size.</td> <td>The size of the linked list is variable.</td> </tr> <tr> <td>Inserting a new element is difficult.</td> <td>Insertion and deletion are simpler.</td> </tr> <tr> <td>Access is permitted at random.</td> <td>No random access is possible.</td> </tr> <tr> <td>Elements are in relatively close or contiguous.</td> <td>The elements are not contiguous.</td> </tr> <tr> <td>No additional room is required for the following pointer.</td> <td>The following pointer requires additional memory.</td> </tr> </table> <h3>Functionality</h3> <p>Since linked lists and arrays are both linear data structures that hold objects, they can be utilised in similar ways for the majority of applications.</p> <p>The following are some examples of linked list applications:</p> <ul> <li>Stacks and queues can be implemented using linked lists.</li> <li>When we need to express graphs as adjacency lists, we can use a linked list to implement them.</li> <li>We can also use a linked list to contain a mathematical polynomial.</li> <li>In the case of hashing, linked lists are employed to implement the buckets.</li> <li>When a programme requires dynamic memory allocation, we can utilize a linked list because linked lists are more efficient in this instance.</li> </ul> <h2>Conclusion</h2> <p>Linked lists are data structures used to hold data elements in a linear but non-contiguous form. A linked list is made up of nodes with two components each. The first component is made up of data, while the second half has a pointer that stores the memory address of the following member of the list.</p> <p>As a sign that the linked list has ended, the last item in the list has its next pointer set to NULL. The Head is the first item on the list. The linked list allows for a variety of actions such as insertion, deletion, traversal, and so on. Linked lists are favoured over arrays for dynamic memory allocation.</p> <p>Linked lists are hard to print or traverse because we can't access the elements randomly like arrays. When compared to arrays, insertion-deletion procedures are less expensive.</p> <p>In this tutorial, we learned everything there is to know about linear linked lists. Linked lists can also be doubly linked or circular. In our forthcoming tutorials, we will go through these lists in detail.</p> <hr></data>
Број чворова
Док се прелази преко повезане листе, може се извршити процес бројања броја чворова. У претходном приступу, видели смо да ако треба да убацимо/избришемо чвор или прикажемо садржај повезане листе, морамо да пређемо повезану листу од почетка.
Постављање бројача и повећање, као и кретање кроз сваки чвор, обезбедиће нам број чворова на повезаној листи.
Разлике између низа и повезане листе:
Низ | Повезана листа |
---|---|
Низови имају дефинисану величину. | Величина повезане листе је променљива. |
Убацивање новог елемента је тешко. | Уметање и брисање су једноставнији. |
Приступ је дозвољен насумично. | Није могућ случајни приступ. |
Елементи су релативно блиски или суседни. | Елементи нису суседни. |
За следећи показивач није потребан додатни простор. | Следећи показивач захтева додатну меморију. |
Функционалност
Пошто су повезане листе и низови линеарне структуре података које садрже објекте, могу се користити на сличан начин за већину апликација.
Следе неки примери апликација за повезане листе:
- Стогови и редови се могу имплементирати помоћу повезаних листа.
- Када треба да изразимо графове као листе суседности, можемо да користимо повезану листу да бисмо их применили.
- Такође можемо користити повезану листу да садржи математички полином.
- У случају хеширања, повезане листе се користе за имплементацију буцкета.
- Када програм захтева динамичку алокацију меморије, можемо да користимо повезану листу јер су повезане листе ефикасније у овом случају.
Закључак
Повезане листе су структуре података које се користе за држање елемената података у линеарном, али неконтинуираном облику. Повезана листа се састоји од чворова са по две компоненте. Прву компоненту чине подаци, док друга половина има показивач који чува меморијску адресу следећег члана листе.
Као знак да је повезана листа завршила, последња ставка на листи има следећи показивач постављен на НУЛЛ. Глава је прва ставка на листи. Повезана листа омогућава различите радње као што су уметање, брисање, прелазак и тако даље. Повезане листе су фаворизоване у односу на низове за динамичку алокацију меморије.
Повезане листе је тешко штампати или прећи јер не можемо да приступимо елементима насумично као низовима. У поређењу са низовима, процедуре уметања-брисања су јефтиније.
У овом водичу научили смо све што се може знати о линеарним повезаним листама. Повезане листе такође могу бити двоструко повезане или кружне. У нашим предстојећим туторијалима, детаљно ћемо проћи кроз ове листе.