Linked Lists
-
Upload
hashim-lucas -
Category
Documents
-
view
32 -
download
4
description
Transcript of Linked Lists
![Page 1: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/1.jpg)
Linked ListsLinked Lists
![Page 2: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/2.jpg)
Outline
• Why linked lists?• Linked lists basics• Implementation• Basic primitives
Searching Inserting Deleting
![Page 3: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/3.jpg)
Why linked lists?
• The default implementation for storing a set of objects is an array int v[10];
denotes the allocation of 10 int variables
• Arrays are efficient for many purposes (e.g., fast access to elements), but have several limitations
![Page 4: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/4.jpg)
Limitations of arrays (1)
• Their size must be fixed in advance
At compile time (statically allocated)int mydata[100];
At run time (dynamically allocated)int *mydata;mydata = (int*)malloc(sizeof(int)*100);
• In theory it is possible, for a dynamically allocated array to resize it using realloc but it tends to be quite inefficient E.g., reallocate a large array to add 1 element
![Page 5: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/5.jpg)
Limitations of arrays (2)
• Because of first limitation, arrays are often over-sized
• To deal with dynamically changing sets of data, programmers usually allocate arrays which seem "large enough“.
• Problems: Low utilization of arrays (you allocate a size X but use at
most a fraction of it) and the space is wasted If the program ever needs to process more than X data,
the code breaks
![Page 6: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/6.jpg)
Limitation of arrays (3)
• Inserting elements to keep a given order is inefficient
• Example: If elements of the array represent an order of arrival
(a[0] is last arrived) inserting a new element implies moving all elements one position ahead
![Page 7: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/7.jpg)
Array vs. linked lists
• Linked lists solve limitations of arrays by paying in terms of efficiency of access of elements
• Arrays: allocate memory for all its elements stored in contiguous
memory locations (appears as one block of memory)
• Linked lists: allocate space for each element separately in its own
block of memory called a "linked list element" or "node". The list gets is overall structure by using pointers to
connect all its nodes together like the links in a chain.
![Page 8: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/8.jpg)
Array vs. linked lists
• Array– int v[4];
• List– ????
253-1
v[0]v[1]v[2]v[3]
v2
5
3
-1
?
![Page 9: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/9.jpg)
Linked lists
• Each list node contains two fields: a "data" field to store whatever element type the list
holds and a "next" field which is a pointer used to link one
node to the next node.
• Each node is allocated with malloc() and it continues to exist until it is explicitly deallocated with free()
![Page 10: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/10.jpg)
Arrays vs. linked lists
Arrays Lists
Access time
+ (independent of
array size – random access)
-(proportional to list
size – sequential access)
Utilization
- (over allocation
typical)
+ (allocate what you
need)
Modification of element order
- (requires
movement of elements)
+ (insert where
needed by moving pointers)
![Page 11: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/11.jpg)
Lists (cont.)
• Variants: Double linked lists
• The element possesses a pointer also to the previous element
Circular lists• The last element in the list is linked to the head
![Page 12: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/12.jpg)
Lists (cont.)
• Variants: Lists with sentinel
• Head or tail or both exist as fictitious elements to manage special cases at the boundary
Ordered Lists• Starting from the head the elements (i.e., the keys)
have an order (increasing or decreasing)
![Page 13: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/13.jpg)
Array vs. linked lists
• Array– int v[4];
• List– List* Head;
253-1
v[0]v[1]v[2]v[3]
v2
5
3
-1
Head
![Page 14: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/14.jpg)
Lists - (cont.)
• PrimitivesInsert (at the head of the list)SearchDeleteInsertSorted
• NOTE: The ordering of a list is not immediate It requires double pointers or auxiliary lists
![Page 15: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/15.jpg)
Lists: Basic operations
•Different from vector based data structures, operation on a list requires pointer manipulation
•Element creation: Using malloc()
•Initialization of a list A pointer to list initialized to NULL
•Insertion/deletion of an element Movement of pointers
![Page 16: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/16.jpg)
Lists - list.h
typedef struct e{ int key; List* next;
} List;
List* Insert(List*,int); /* modifies the head */List* Search(List*, int);void Display(List*);List* Delete(List*,int, int*); /* modifies the head */
List* InsertSorted(List*,int); /* modifies the head*/
![Page 17: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/17.jpg)
Lists - list.c (1)
#include <stdio.h>
List* Insert( List* head, int val){List* p;
p = newE();
p->key = val; /* più vari campi */p->next = head;head = p;return head;
}
![Page 18: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/18.jpg)
Lists - list.c (2)
List* Search( List* head, int val){List* p;
p = head;while(p != NULL){
if( p->key == val) return(p);
else p = p->next;
}return(NULL);
}
![Page 19: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/19.jpg)
Lists - list.c (3)
void Display(List* head){List* p;
p = head;
while( p != NULL){
printf(“%5d\n”,p->val);p = p->next;
}}
![Page 20: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/20.jpg)
Lists - list.c (4)
•The previous examples are in fact two applications of a generic “visit” function that does something on ALL list elements
void Visit (List* head){List* p;
p = head;while( p != NULL){
/* do something on p->key */p = p->next;
}}
![Page 21: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/21.jpg)
Example of usage
int val;List* head, p;…val = 1;p = Search (head, val);if (p == NULL)printf(“Value not found!\n”);
elseprintf(“Value found!\n”);
![Page 22: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/22.jpg)
Lists: Deleting an element
• Deleting an element q (after element p)
After
p->next = q->next;free(q);
Beforep q
p->next q->next
p q
![Page 23: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/23.jpg)
Delete it
Search where is it
Delete from head
Lists - list.c (3)
List* Delete( List* head, int val, int* status){List *p, *q;
p = q = head;if (head != NULL){ if (p->key == val) { /* found */
head = p->next;free(p);*status = SUCCESS;return head;
} else {while(q->next != NULL) {
p = q;q = q->next;if (q->key == val) {
p->next = q->next;free(q);*status = SUCCESS;return head;}}}}
*status = FAILURE;return head;
}
![Page 24: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/24.jpg)
Lists: Inserting an element
• Insertion of node q after node p
Before
After
3 6p
5q
p->next
3 6p
5p->next q q->next
q->next = p->next;p->next = q;
![Page 25: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/25.jpg)
Lists - list.c (4)
List* InsertSorted(List* head, int val){List *p, *q=head;
/* head insertion */if( (q == NULL) || (q->key > val)){
p = newE();
p->key = val;p->next = head;head = p;
return head;}
![Page 26: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/26.jpg)
Lists - list.c (4)
/* search where to insert */while( q->next != NULL) { if( q->next->key > val) {
p = newE(); p->key = val; p->next = q->next; q->next = p; return head;
} q = q->next;}
q is != NULL, so q->next is defined
![Page 27: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/27.jpg)
Lists - list.c (4)
/* tail insertion: q->next is null here*/
p = newE();p->key = val;p->next = NULL;q->next = p;return head;
}
![Page 28: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/28.jpg)
Stacks and Queues
![Page 29: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/29.jpg)
Stack
•Use a LIFO (Last In First Out) policy The last element inserted is the first that will be
deleted Eg.: a stack of books
•Implementation in terms of lists•Primitives:PushPopTopEmpty
![Page 30: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/30.jpg)
Stack and queues
•Dynamic Push Insertion in head
•Dynamic Pop Deletion from head
List* head=NULL; //init.
head = Push (head, val); //call List* Push (List*,int val){ List* p; p = newE(); p->next = head; p->key = val; head = p;
}
List* Pop(List* head, int* val){ List* p;
if (head==NULL) { printf(“Stack Underflow\n”); } else {
*val=head->key;p=head;head=p->next;free(p);
return head; }}
![Page 31: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/31.jpg)
Queues
• Implements a FIFO (First In First Out) policy First inserted item is the first to be extracted (deleted) E.g., a queue of persons to be served
![Page 32: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/32.jpg)
Queues and lists
•Dynamic Enqueue Insert in tail
•Dynamic Dequeue Extract from the head
• Given the huge number of accesses to the tail of the list, it is convenient to use an explicit pointer tail for the queues
![Page 33: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/33.jpg)
Linear queues with lists
• Dynamic Enqueue • Dynamic Dequeue
Function call:pTail = enqueue (&head, pTail, val);
List* enqueue(List** head,List* pTail,int val)
{ List* p; p = newE(); p->key = val; if (pTail==NULL) { //first elem
*head = p;p->next = NULL;
} else {pTail->next = p;}
pTail = p; return pTail;}
head = dequeue (head, &pTail, &val);
List* dequeue(List* head,List** pTail,int* val)
{ List* p;
if (head==NULL) {printf(“Queue underflow\n”);
} else {*val = head->key;p = head;if (head == *pTail) {/* one-element queue */
*pTail=NULL; head=NULL;} else { head = head->next;}
free (p); } return head;}
List* head=NULL, tail; //init.
![Page 34: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/34.jpg)
Circular queues
•Dynamic Enqueue Insert in tail
•Dynamic Dequeue Extract from the head
• Usage of pointer pTail for insertion and deletion: last element points to first one
pTailpTail->next
![Page 35: Linked Lists](https://reader036.fdocuments.in/reader036/viewer/2022062516/56812c44550346895d90ca15/html5/thumbnails/35.jpg)
Queues and lists - (cont.)
• Dynamic Enqueue • Dynamic Dequeue
Function call:pTail = enqueue(pTail, val);
List* enqueue(List* pTail, int val){ List* pNew; pNew = newE(); p->key = val; /* ……. */ if (pTail==NULL) {
pTail = pNew; pTail->next = pTail;
} else { pNew->next = pTail->next; pTail->next = pNew; pTail = pNew;}
return pTail;}
Function call:pTail = dequeue(pTail, val);
List* dequeue(List* pTail, int* val,int* status)
{ List* pOld; if (pTail=!=NULL) {
*status = SUCCESS;if (pTail == pTail->next){
*val = pTail->key;free(pTail);pTail = NULL;}
else{pOld = pTail->next;*val = pOld->key;pTail->next = pOld->next;free(pOld);}}
return pTail;}