0% found this document useful (0 votes)
12 views31 pages

Linked List

The document explains the concept of linked lists, highlighting their advantages over array implementations, particularly in terms of adding and deleting elements without heavy data movement. It details the structure of a linked list, including nodes and pointers, and provides code examples for adding and deleting elements, as well as handling memory management issues such as garbage and dangling references. Additionally, it discusses the importance of destructors in cleaning up dynamically allocated memory when a linked list goes out of scope.

Uploaded by

Anas Aqeel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views31 pages

Linked List

The document explains the concept of linked lists, highlighting their advantages over array implementations, particularly in terms of adding and deleting elements without heavy data movement. It details the structure of a linked list, including nodes and pointers, and provides code examples for adding and deleting elements, as well as handling memory management issues such as garbage and dangling references. Additionally, it discusses the importance of destructors in cleaning up dynamically allocated memory when a linked list goes out of scope.

Uploaded by

Anas Aqeel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

LINKED LIST

 Given an ordered-list:
 What happens when we add/delete an element to the list?

 In the array implementation, such cases require heavy


data movement which is very costly.

 In most cases, the data is processed in a strictly sequential


order.

 Therefore all that is required is the access to next element.


 In our previous mapping, the next element happens to
be the elemental at the next index in the array.

 If we can some how tell where the next element is


stored, we can eliminate this restriction of placing the
next element at the next physical location!

 This gives rise to the notion of logical adjacency as


opposed to physical adjacency.
 In that case, in order to access the elements
of the list, all we need is a starting point and
some mechanism to move from one element
to the next.
 In other words, we need a starting point
and a link from one element to the next.

1 2 3 4
 We can only travel in the direction of the link.

 We have a chain like structure and we can access


the elements in the chain by just following the links
in the chain.

 Such an organization is known as a linked-list.


CHAINING & LINK LIST
LINKED-LISTS

 This organization rids us from the


requirement to maintain the logical as
well as physical adjacency.
 Now all we need to maintain is the logical
sequences and two logically adjacent
elements need to not be physically
next to each other.
TRAIN & LINK LIST
Engine

Bogies

Starting point of linklist

root 5 8 10 15 

data elements
BOGIE
Trolley

Connector

Next Data

Node
LINKED-LISTS
 We can implement this organization by storing the information
and handle to the next element with the other data as follows:-

struct node {
node * next; // handle to next list element
data_type data;
};

node * root; // starting point - handle to first list element


root =  // initialize head to  - the end marker
LINKED-LISTS
 A list node and the resulting list looks
like as shown below:

Data Next

root 2 5 8 10 15 
LINKED-LISTS – TRAVERSAL
void traverse (node * root)
{
node * current = root;
while ( current !=  ) {
process data at current;
current = next field of current element
}
} root 2 5 8 10 15 

current
LINKED-LIST
ADD AN ELEMENT AFTER CURRENT ELEMENT

void add (node * current, data_type data)


{
node * new_element;
new_element = get a new element; //step 1
data field of new_element = data; //step 1

next field of new_element = next field of current; //step 2


next field of current = new_element; //step 3
}
LINKED-LIST – INSERTION
root 2 5 8 10 15 

6
Curr Step 1
new_element = get a new element;
new_Element data field of new_element = data;

root 2 5 8 10 15 

Curr Step 2
6
new_Element next field of new_Element =
next field of current;

root 2 5 8 10 15 

Curr 6
Step 3
new_ Element next field of current = new_element;
LINKED-LIST – WARNING:
FRAGILE, HANDLE LINKS WITH CARE

 If one link is broken, you loose access to all


subsequent elements.
 What happens if you swap the following two lines in
add:
next field of new_element = next field of current; //step 2
next field of current = new_element; //step 3
to
next field of current = new_element; //step 2
next field of new_element = next field of current; //step 3
root 2 5 8 10 15 

7
Step 1 Curr
new_element = get a new element
data field of new_element = data new_element

root 2 5 8 10 15 

7
Curr
Step 2
New_element next field of current = new_element;

This part is no longer accessible


Step 3
next field of new_element =
next field of current;

root 2 5 8 10 15 

7
Curr

new_element
LINKED-LIST
DELETE AN ELEMENT AFTER CURRENT ELEMENT

void delete (node * current)


{
node * temp = next field of current;
next field of current = next field of next element of current
// same as next field of temp
discard temp
}
LINKED LIST - DELETION

root 5 6 9 12 15 

node * temp = next field of current; Curr temp

root 5 6 9 12 15 

next field of current = temp


next filed of next element of current This element is no longer
Curr accessible
GARBAGE
 When all access paths to a data object are destroyed
but the data object continues to exist, the data object is
said to be garbage.
 Garbage is a less serious but still troublesome problem.
A data object that has become garbage ties up storage
that might otherwise be reallocated for another
purpose.
 A buildup of garbage can force the program to terminate
prematurely because of lack of available free storage.

root 5 6 9 12 15 

temp
This element is no longer
Curr accessible
GARBAGE

This part is no longer accessible

root 2 5 8 10 15 

7
Curr

New Element
LINKED LIST - IMPLEMENTATION USING
DYNAMICALLY ALLOCATED STORAGE

 Handle will be the pointer (memory address) of an element in


the linked list.
 Space may be acquired at run-time on request from free store
using new.
 At a point in time when a memory area pointed to by a pointer
is no longer required, it can be returned back to free store
using delete.
 We should always return storage after we no longer need it.
 Once an area is freed, it is improper and quite dangerous to
use it.
DANGLING REFERENCES
A dangling reference is an access path that continues to exist after the life
time of the associated data object.

ObjectTypeA *p, *q;


p
p = new ObjectTypeA;
q = p; q

delete q; q = NULL; p
What happens to p?
q 

It’s a “dangling reference”!


GARBAGE
When all access paths to a data object are destroyed but the data object continues
to exist, the data object is said to be garbage.

ObjectTypeA *p, *q;


p
p = new ObjectTypeA;
q = new ObjectTypeA; q

p
q = p;

What happens to the space that was pointed to by q?

It’s “garbage”!
DANGLING REFERENCES AND
GARBAGE
 Dangling references are particularly serious
problem for storage management, as they might
compromise the integrity of the entire run-time
structure during program execution.
 Garbage is a less serious but still troublesome
problem. A data object that has become
garbage ties up storage that might otherwise be
reallocated for another purpose.
 A buildup of garbage can force the program to
terminate prematurely because of lack of
available free storage.
LINKED LIST - IMPLEMENTATION USING
DYNAMICALLY ALLOCATED STORAGE
struct Node {
int data;
Node *next;
};

Class LinkedList {
private:
Node * root;
public:
LinkedList() { root = NULL; }
void add (int data);
void remove (int data);
void print ();
~LinkedList();
};
void LinkedList:: print()
{
Node *current = root;
while (current != NULL) {
cout << current->data;
current = current->next;
}

root 2 5 8 10 15 

current
bool LinkedList::add(int data)
{
Node *temp = new Node;
if (temp == NULL) return false;
else {
temp->data = data;
Node *current, *previous;
current = root;
while (current != NULL && current->data < data;) {
previous = current;
current = current->next;
}
temp -> next = current;
if (current == root) root = temp;
temp
else previous->next = temp;
return true;
} 9
}

root 2 5 8 10 15 

Previous Current
void LinkedList::remove(int data)
{
Node *current, *previous;
current = root;
while (current != NULL && current->data < data) {
previous = current;
current = current->next
}
if (current != NULL && current->data == data) {
if (current == root)
root = root -> next;
else
previous->next = current->next;
delete current;
}
}
THE DESTRUCTOR
 The destructor is the counterpart of the constructor.
 It is a member function that is called automatically when
a class object goes out of scope.
 Its purpose is to perform any cleanup work necessary
before an object is destroyed.
 Destructors are required for more complicated classes,
where they're used to release dynamically allocated
memory.
~LINKEDLIST() { }
struct Node { int data; Node *next; };
Class LinkedList {private: Node * root; public: … ~LinkedList(); };

LinkedList A; A.add(2); A.add(5); A.add(10); A.add(15); A.add(8);

 root

A
2 5 8 10 15 

• A goes out of scope. What Happens?


• When destructor is called, what is deleted?
• What Happens to this memory area?
• It is garbage!
• Destructor must also delete this area.
~LINKEDLIST()
~LinkedList()
{
Node *temp1, *temp2;
temp1 = root;
while (temp1 != NULL)
{
temp2 = temp1->next;
delete temp1;
temp1 = temp2;
}
}

 
root

A
2 5 8 10 15 

temp1 temp2

You might also like