Download presentation
Presentation is loading. Please wait.
1
Linked List Sudeshna Sarkar
2
Self Referential Structures
A structure referencing itself – how? So, we need a pointer inside a structure that points to a structure of the same type. struct list { int data; struct list *next; } ; typedef struct list ELEMENT; typedef ELEMENT * LINK;
3
Linked Lists A singly linked list is a concrete data structure consisting of a sequence of nodes Each node stores element link to the next node next node elem NULL A B C D
4
Linear Linked Lists head A B C D NULL Data type of head?
5
42 98 12 6 heap stack head
6
Linear Linked Lists tail head A B C D NULL Data type of head?
7
Representation with Dummy Node
Ignore 10 17 head dummy node Insertion at the beginning is the same as insertion after the dummy node
8
Keeping track of a linked list:
Must know the pointer to the first element of the list (called start, head, etc.). Linked lists provide flexibility in allowing the items to be rearranged efficiently. Insert an element. Delete an element. Spring 2012 Programming and Data Structure
9
struct list a, b, c; a.data = 1; b.data = 2; c.data = 3; a.next = b.next = c.next = NULL; a b c 1 NULL 2 NULL 3 NULL data next data next data next
10
Chaining these together
a.next = &b; b.next = &c; a b c 1 2 3 NULL data next data next data next What are the values of : a.next->data a.next->next->data 2 3
11
Header file : list.h #include <stdio.h>
#include <stdlib.h> typedef char DATA; struct list { DATA d; struct list * next; }; typedef struct list ELEMENT; typedef ELEMENT * LINK;
12
Storage allocation LINK head ; head = malloc (sizeof(ELEMENT));
head->d = ‘n’; head->next = NULL; creates a single element list. head n NULL
13
Storage allocation head->next = malloc (sizeof(ELEMENT));
head->next->d = ‘e’; head->next->next = NULL; A second element is added. head n e NULL
14
Storage allocation head->next->next = malloc (sizeof(ELEMENT));
head->next->next->d = ‘w’; head->next->next-> = NULL; We have a 3 element list pointed to by head. The list ends when next has the sentinel value NULL. head n e w NULL
15
List operations (ii) how to insert such a structure into the LIST,
(i) How to initialize such a self referential structure (LIST), (ii) how to insert such a structure into the LIST, (iii) how to delete elements from it, (iv) how to search for an element in it, (v) how to print it, (vi) how to free the space occupied by the LIST?
16
Produce a list from a string (recursive version)
#include “list.h” LINK StrToList (char s[]) { LINK head ; if (s[0] == ‘\0’) return NULL ; else { head = malloc (sizeof(ELEMENT)); head->d = s[0]; head->next = StrToList (s+1); return head; }
17
list from a string (iterative version)
#include “list.h” LINK SToL (char s[]) { LINK head = NULL, tail; int i; if (s[0] != ‘\0’) { head = malloc (sizeof(ELEMENT)); head->d = s[0]; tail = head; for (i=1; s[i] != ‘\0’; i++) { tail->next = malloc(sizeof(ELEMENT)); tail = tail->next; tail->d = s[i]; } tail->next = NULL; return head; list from a string (iterative version)
18
Inserting at the Head Allocate a new node Insert new element
Make new node point to old head Update head to point to new node Linked Lists
19
Removing at the Head Update head to point to next node in the list
Allow garbage collector to reclaim the former first node Linked Lists
20
Linear Linked List with tail
head A B C D NULL
21
Inserting at the Tail Allocate a new node Insert new element
Have new node point to null Have old last node point to new node Update tail to point to new node Linked Lists
22
Removing at the Tail Removing at the tail of a singly linked list cannot be efficient! There is no constant-time way to update the tail to point to the previous node Linked Lists
23
Insertion To insert a data item into an ordered linked list involves:
creating a new node containing the data, finding the correct place in the list, and linking in the new node at this place.
24
Example of an Insertion
first prev ptr 3 5 8 7 new Create new node for the 7 Find correct place – when ptr finds the 8 (7 < 8) Link in new node with previous (even if last) and ptr nodes Also check insertion before first node!
25
Header file : list.h #include <stdio.h>
#include <stdlib.h> struct list { int data; struct list * next; }; typedef struct list ELEMENT; typedef ELEMENT * LINK;
26
Create_node function Link create_node(int data) { LINK new;
new = (LINK) malloc (sizeof (ELEMENT)); new -> data = data; return (new); }
27
Adding an Element to a Linked List
Involves two steps: Finding the correct location Three possible positions: The front The end Somewhere in the middle Doing the work to add the node
28
Inserting to the Front There is no work to find the correct location
head 93 head 48 17 142 There is no work to find the correct location Empty or not, head will point to the right location
29
Inserting to the End // // Find the end of the list (when at NIL)
head 93 // 48 17 142 // Find the end of the list (when at NIL) Recursion or iteration
30
Inserting to the Middle
head 93 // 142 17 48 142 // Used when order is important Go to the node that should follow the one to add Recursion or iteration
31
The Work to Add the Node newnode = (node *) malloc(sizeof(node));
typedef struct stud { int roll; char name[25]; int age; struct stud *next; } node; node *head; Create the new node Fill in the data field Deal with the next field Point to nil (if inserting to end) Point to current (front or middle) newnode = (node *) malloc(sizeof(node)); newnode->data = new_data newnode->next = current ; current = newnode;
32
Three Types of Insertion
To front To end Get to the end, then add node In middle Get to the node before which the new node is to be inserted.
33
insert at front LINK insertfront (int data, LINK head) {
LINK new, prev, first; new = create_node(data); new -> next = ptr; return new; // return pointer to first node }
34
Insert to end LINK insertend (int data, LINK ptr) { LINK new, head;
new = create_node(data); head = ptr; if (ptr == NULL ) { new -> next = NULL; return new; } while (ptr->next != NULL) ptr = ptr -> next; ptr -> next = new; new -> next = NULL; return head;
35
Sorted insert function
LINK insert (int data, LINK ptr) { LINK new, prev, first; new = create_node(data); if (ptr == NULL || data < ptr -> value){ // insert as new first node new -> next = ptr; return new; // return pointer to first node }
36
else { // not first one first = ptr; // remember start prev = ptr; ptr = ptr -> next; // second while (ptr != NULL && data > ptr -> data) { ptr = ptr -> next; } prev -> next = new; // link in new -> next = ptr; //new node return first; } // end else } // end insert
37
Deletion To delete a data item from a linked list involves (assuming it occurs only once!): finding the data item in the list, and linking out this node, and freeing up this node as free space.
38
Example of Deletion first prev ptr 3 5 8 When ptr finds the item to be deleted, e.g. 8, we need the previous node to make the link to the next one after ptr (i.e. ptr -> next). Also check whether first node is to be deleted.
39
// delete the item from ascending list
LINK delete_item(int data, LINK ptr) { LINK prev, first; first = ptr; // remember start if (ptr == NULL) { return NULL; } else if (data == ptr -> data) // first node { ptr = ptr -> next; // second node free(first); // free up node return ptr; // second
40
else // check rest of list
{ prev = ptr; ptr = ptr -> next; // find node to delete while (ptr != NULL && data > ptr->data) ptr = ptr -> next; }
41
if (ptr == NULL || data != ptr->data)
// NOT found in ascending list // nothing to delete { return first; // original } else // found, delete ptr node prev -> next = ptr -> next; free(ptr); // free node } // end delete
42
Representation with Dummy Node
head dummy node Insertion at the beginning is the same as insertion after the dummy node
43
Initialization head typedef struct list { int data; struct list *next;
Write a function that initializes LIST typedef struct list { int data; struct list *next; } ELEMENT; ELEMENT* Initialize (int element) { ELEMENT *head; head = (ELEMENT *)malloc(sizeof(data)); // Create initial node head->data = element; head -> next = NULL; return head; }
44
Insert head head
45
ELEMENT* Insert(ELEMENT *head, int element, int position) {
int i=0; ELEMENT *temp, *new; if (position < 0) { printf("\nInvalid index %d\n", position); return head; } temp = head; for(i=0;i<position;i++){ temp=temp->next; if(temp==NULL) { new = (ELEMENT *)calloc(1,sizeof(ELEMENT)); new ->data = element; new -> next = temp -> next; temp -> next = new;
46
Delete head temp head temp
47
ELEMENT* Delete(data *head, int position) {
int i=0;data *temp,*hold; if (position < 0) { printf("\nInvalid index %d\n", position); return head; } temp = head; while ((i < position) && (temp -> next != NULL)) { temp = temp -> next; i++; if (temp -> next == NULL) { hold = temp -> next; temp -> next = temp -> next -> next; free(hold);
48
Searching a data element
int Search (ELEMENT *head, int element) { int i; ELEMENT *temp; i = 0; temp = head -> next; while (temp != NULL) { if (temp -> x == element) return TRUE; temp = temp -> next; i++; } return FALSE;
49
Printing the list void Print (ELEMENT *head) { ELEMENT *temp;
temp = head -> next; while (temp != NULL) { printf("%d->", temp -> data); temp = temp -> next; }
50
Print the list backwards
. head How can you when the links are in forward direction ? Can you apply recursion?
51
Print the list backwards
void PrintArray(ELEMENT *head) { if(head -> next == NULL) { //boundary condition to stop recursion printf(" %d->",head -> data); return; } PrintArray(head -> next); // calling function recursively printf(" %d ->",head -> data); // Printing current elemen
52
Free the LIST head temp1 temp2
We can free temp1 only after we have retrieved the address of the next element (temp2) from temp1.
53
Free the list void Free(ELEMENT *head) { ELEMENT *temp1, *temp2;
temp1 = head; while(temp1 != NULL) /*boundary condition check*/ { temp2 = temp1 -> next; free(temp1); temp1 = temp2; }
54
/* Count a list recursively */
int count (LINK head) { if (head == NULL) return 0; return 1+count(head->next); } /* Count a list iteratively */ int count (LINK head) { int cnt = 0; for ( ; head != NULL; head=head->next) ++cnt; return cnt; }
55
/* Print a List */ void PrintList (LINK head) { if (head == NULL)
printf (“NULL”) ; else { printf (“%c --> “, head->d) ; PrintList (head->next); }
56
/* Concatenate two Lists */
void concatenate (LINK ahead, LINK bhead) { if (ahead->next == NULL) ahead->next = bhead ; else concatenate (ahead->next, bhead); }
57
Delete a list and free memory
/* Recursive deletion of a list */ void delete_list (LINK head) { if (head != NULL) { delete_list (head->next) ; free (head) ; /* Release storage */ }
58
Array versus Linked Lists
Arrays are suitable for: Inserting/deleting an element at the end. Randomly accessing any element. Searching the list for a particular value. Linked lists are suitable for: Inserting an element. Deleting an element. Applications where sequential access is required. In situations where the number of elements cannot be predicted beforehand. Spring 2012 Programming and Data Structure
59
Types of Lists Depending on the way in which the links are used to maintain adjacency, several different types of linked lists are possible. Linear singly-linked list (or simply linear list) One we have discussed so far. A B C head Spring 2012 Programming and Data Structure
60
Programming and Data Structure
Circular linked list The pointer from the last element in the list points back to the first element. A B C head Spring 2012 Programming and Data Structure
61
Programming and Data Structure
Doubly linked list Pointers exist between adjacent nodes in both directions. The list can be traversed either forward or backward. Usually two pointers are maintained to keep track of the list, head and tail. A B C head tail Spring 2012 Programming and Data Structure
62
List is an Abstract Data Type
What is an abstract data type? It is a data type defined by the user. Typically more complex than simple data types like int, float, etc. Why abstract? Because details of the implementation are hidden. When you do some operation on the list, say insert an element, you just call a function. Details of how the list is implemented or how the insert function is written is no longer required. Spring 2012 Programming and Data Structure
63
Conceptual Idea List implementation Insert and the related functions
Delete Traverse Spring 2012 Programming and Data Structure
64
Few Exercises to Try Out
Write a function to: Concatenate two given list into one big list. node *concatenate (node *head1, node *head2); Insert an element in a linked list in sorted order. The function will be called for every element to be inserted. void insert_sorted (node **head, node *element); Always insert elements at one end, and delete elements from the other end (first-in first-out QUEUE). void insert_q (node **head, node *element) node *delete_q (node **head) /* Return the deleted node */ Spring 2012 Programming and Data Structure
65
Thank You
66
Insertion After Insertion p2 p1 C A q B
/* Inserting an element in a linked list. */ void insert (LINK p1, LINK p2, LINK q) { p1->next = q; q->next = p2; } After Insertion p2 p1 A C q B
67
Insertion Before Insertion p2 p1 C A q B
Insertion in a list takes a fixed amount of time once the position in the list is found. Before Insertion p2 p1 A C q B
68
Deletion p 1 2 3 p->next = p->next->next; garbage p
Before deletion p 1 2 3 p->next = p->next->next; garbage p After deletion 1 2 3
69
Deletion p 1 2 3 q = p->next; p->next = p->next->next; p
Before deletion p 1 2 3 q = p->next; p->next = p->next->next; p After deletion 1 2 3 q free (q) ;
70
Print the list backwards
. head How can you when the links are in forward direction ? Can you apply recursion?
71
Print the list backwards
void PrintArray(ELEMENT *head) { if(head -> next == NULL) { /*boundary condition to stop recursion*/ printf(" %d->",head -> data); return; } PrintArray(head -> next); /* calling function recursively*/ printf(" %d ->",head -> data);/* Printing current elemen
72
Free the LIST head temp1 temp2
We can free temp1 only after we have retrieved the address of the next element (temp2) from temp1.
73
Free the list (iterative)
void Free(ELEMENT *head) { ELEMENT *temp1, *temp2; temp1 = head; while(temp1 != NULL) /*boundary condition check*/ { temp2 = temp1 -> next; free(temp1); temp1 = temp2; }
74
Delete a list and free memory (recursive)
/* Recursive deletion of a list */ void delete_list (LINK head) { if (head != NULL) { delete_list (head->next) ; free (head) ; /* Release storage */ }
75
/* Count a list recursively */
int count (LINK head) { if (head == NULL) return 0; return 1+count(head->next); } /* Count a list iteratively */ int count (LINK head) { int cnt = 0; for ( ; head != NULL; head=head->next) ++cnt; return cnt; }
76
/* Print a List */ void PrintList (LINK head) { if (head == NULL)
printf (“NULL”) ; else { printf (“%c --> “, head->d) ; PrintList (head->next); }
77
/* Concatenate two Lists */
void concatenate (LINK ahead, LINK bhead) { if (ahead->next == NULL) ahead->next = bhead ; else concatenate (ahead->next, bhead); }
78
Assignment:Reverse a list
head 1 2 3 4 head 1 2 3 4
79
Doubly linked list A B C Assignment : Insertion, deletion in a doubly
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.