Lecture 4-linked list implementation (preliminaries)
Lecture 4-linked list implementation (preliminaries)
Data Structures
Spring 2022
Link List - Implementation Preliminaries
1
Agenda
3
Array Operations: Search Algorithms
4
Limitation of Arrays
6
Linked List
• Linked list nodes composed of two parts
– Data part
Stores an element of the list
– Next (pointer) part
Stores link/address/pointer to next element
Stores Null value, when no next element
7
Simple Linked List Class (1)
• We use two classes: Node and List
• Declare Node class for the nodes
– data: double-type data in this example
– next: a pointer to the next node in the list
class Node {
public:
double data; // data
Node* next; // pointer to next Node
};
8
Simple Linked List Class (2)
• Declare List, which contains
– head: a pointer to the first node in the list
– Since the list is empty initially, head is set to NULL
class List {
public:
List(void) { head = NULL; } //
constructor
~List(void); //
destructor
Operations of List
10
Inserting a New Node
• bool Insert(int index, double x)
– Insert a node with data equal to x at the index elements
– If the insertion is successful
Return true
Otherwise, return false
– If index is <= 0 or > length+1 of the list, the insertion will fail
• Steps
1. Locate the node at the position one less than index [list is
indexed from 1 to n]
2. Allocate memory for the new node, copy data into node
3. Point the new node to its successor (next node)
4. Point the new node’s predecessor (preceding node) to the
new node
11
Insertion After The Last Element (1)
• Suppose current points to the last element of the list
– We can add a new last item x by doing this
A1 A2 A3
head current
Steps
• Locate the index element
current->next = new • Allocate memory for the new
Node(); node
current = current->next; • Copy data into node
current->data = x; • Point the new node to its
current->next = null; successor (next node)
• Point the new node’s
predecessor (preceding node) to
12
the new node
Insertion After The Last Element (2)
• Suppose current points to the last element of the list
– We can add a new last item x by doing this
A1 A2 A3
head current
Steps
• Locate the index element
current->next = new • Allocate memory for the new
Node(); node
current = current->next; • Copy data into node
current->data = x; • Point the new node to its
current->next = null; successor (next node)
• Point the new node’s
predecessor (preceding node) to
13
the new node
Insertion After The Last Element (3)
• Suppose current points to the last element of the list
– We can add a new last item x by doing this
A1 A2 A3
head current
Steps
• Locate the index element
current->next = new • Allocate memory for the new
Node(); node
current = current->next; • Copy data into node
current->data = x; • Point the new node to its
current->next = null; successor (next node)
• Point the new node’s
predecessor (preceding node) to
14
the new node
Insertion After The Last Element (4)
• Suppose current points to the last element of the list
– We can add a new last item x by doing this
A1 A2 A3 x
head current
Steps
• Locate the index element
current->next = new • Allocate memory for the new
Node(); node
current = current->next; • Copy data into node
current->data = x; • Point the new node to its
current->next = null; successor (next node)
• Point the new node’s
predecessor (preceding node) to
15
the new node
Insertion After The Last Element (4)
• Suppose current points to the last element of the list
– We can add a new last item x by doing this
A1 A2 A3 x
head current
Steps
• Locate the index element
current->next = new • Allocate memory for the new
Node(); node
current = current->next; • Copy data into node
current->data = x; • Point the new node to its
current->next = null; successor (next node)
• Point the new node’s
predecessor (preceding node) to
16
the new node
Insertion At The Middle (1)
• Suppose current points to the middle element of the list
– We can add a new item x by doing this
A1 A2 A3
head current
A1 A2 A3
head current
Steps
• Locate the index element
• Allocate memory for the new
node tmp
• Copy data into node tmp = new Node();
• Point the new node to its tmp->data= x;
successor (next node) tmp->next = current-
>next;
• Point the new node’s current->next = tmp;
predecessor (preceding node) to
18
the new node
Insertion At The Middle (1)
• Suppose current points to the middle element of the list
– We can add a new item x by doing this
A1 A2 A3
head current
x
Steps
• Locate the index element
• Allocate memory for the new
node tmp
• Copy data into node tmp = new Node();
• Point the new node to its tmp->data= x;
successor (next node) tmp->next = current-
>next;
• Point the new node’s current->next = tmp;
predecessor (preceding node) to
19
the new node
Insertion At The Middle (1)
• Suppose current points to the middle element of the list
– We can add a new item x by doing this
A1 A2 A3
head current
x
Steps
• Locate the index element
• Allocate memory for the new
node
tmp
• Copy data into node tmp = new Node();
• Point the new node to its tmp->data= x;
successor (next node) tmp->next = current-
>next;
• Point the new node’s current->next = tmp;
predecessor (preceding node) to
20
the new node
Insertion At The Middle (1)
• Suppose current points to the middle element of the list
– We can add a new item x by doing this
A1 A2 A3
head current
x
Steps
• Locate the index element
• Allocate memory for the new
node
tmp
• Copy data into node tmp = new Node();
• Point the new node to its tmp->data= x;
successor (next node) tmp->next = current-
>next;
• Point the new node’s current->next = tmp;
predecessor (preceding node) to
21
the new node
Inserting a New Node (2)
• Possible cases of Insert
1. Insert into an empty list
2. Insert at front
3. Insert at back
4. Insert in middle
22
Inserting a New Node (3)
bool List::Insert(int index, double x) {
Return false for
if (index <= 0) return false;
negative index values.
int currIndex = 2;
Return false signal to
Node* current = head; show index has
while (current && index > currIndex) { negative value
current = current->next;
currIndex++;
}
if (index > 1 && current == NULL) return false;
int currIndex = 2;
Node* current = head;
while (current && index > currIndex) { Try to locate index’th
current = current->next; node. If it doesn’t exist,
currIndex++; return false
}
if (index > 1 && current == NULL) return false;
int currIndex = 2;
Node* current = head;
while (current && index > currIndex) { Try to locate index’th
current = current->next; node. If it doesn’t exist,
currIndex++; return false
}
if (index > 1 && current == NULL) return false;
int currIndex = 2;
Node* current = head;
while (current && index > currIndex) { Try to locate index’th
current = current->next; node. If it doesn’t exist,
currIndex++; return false
}
if (index > 1 && current == NULL) return false;
int currIndex = 2;
Node* current = head;
while (current && index > currIndex) { Try to locate index’th
current = current->next; node. If it doesn’t exist,
currIndex++; return false
}
if (index > 1 && current == NULL) return false;
28
Finding a Node
• int Find(double x)
– Search for a node with the value equal to x in the list
– If such a node is found
Return its position
Otherwise, return 0
int List::Find(double x) {
Node* current = head;
int currIndex = 1;
while (current && current->data != x) {
current = current->next;
currIndex++;
}
if (current) return currIndex;
return 0;
}
29
Deleting a Node – Example (1)
• Deleting item A2 from the list
A1 A2 A3
current
30
Deleting a Node – Example (2)
• Deleting item A2 from the list
A1 A2 A3
current
current->next = current->next->next;
31
Deleting a Node – Example (3)
• Deleting item A2 from the list
A1 A2 A3
current
32
Deleting a Node – Example (4)
• Deleting item A2 from the list
A1 A2 A3
current
33
Deleting a Node – Example (4)
• Deleting item A2 from the list
A1 A2 A3
current
34
Deleting a Node
• int Delete(double x)
– Delete a node with the value equal to x from the list
– If such a node is found return its position
Otherwise, return 0
• Steps
– Find the desirable node (similar to Find)
– Set the pointer of the predecessor of the found node to the
successor of the found node
– Release the memory occupied by the found node
35
Deleting a Node – Implementation (1)
int List::Delete(double x) {
Node* prevNode = NULL;
Node* current = head;
int currIndex = 1;
while (current && current->data != x) { Try to find node with its
prevNode = current; value equal to x.
current = current->next;
currIndex++;
}
if (current) {
if (prevNode) {
prevNode->next = current->next;
delete current;
}
else {
head = current->next;
delete current;
}
return currIndex;
}
return 0;
} 36
Deleting a Node – Implementation (2)
int List::Delete(double x) {
Node* prevNode = NULL;
Node* current = head;
int currIndex = 1;
while (current && current->data != x) {
prevNode = current;
current = current->next; prevNode current
currIndex++;
}
if (current) {
if (prevNode) {
prevNode->next = current->next;
delete current;
}
else {
head = current->next;
delete current;
}
return currIndex;
}
return 0;
} 37
Deleting a Node – Implementation (3)
int List::Delete(double x) {
Node* prevNode = NULL;
Node* current = head;
int currIndex = 1;
while (current && current->data != x) {
prevNode = current;
current = current->next;
currIndex++;
}
if (current) {
if (prevNode) {
prevNode->next = current->next;
delete current;
}
else {
head = current->next;
delete current;
}
return currIndex;
} head current
return 0;
} 38
Quick Participation-2
39
Printing All The Elements
• void DisplayList(void)
– Print the data of all the elements
– Print the number of the nodes in the list
void List::DisplayList()
{
int num = 0;
Node* current = head;
while (current != NULL){
cout << current->data << endl;
current = current->next;
num++;
}
cout << "Number of nodes in the list: " << num << endl;
}
40
Destroying the List
• ~List(void)
– Use the destructor to release all the memory used by the list
– Step through the list and delete each node one by one
List::~List(void) {
Node* current = head;
Node* nextNode = NULL;
while (current != NULL)
{
nextNode = current->next;
delete current; // destroy the current node
current = nextNode;
}
}
41
Using List (1)
Output:
int main(void)
6
{ 7
List list; 5
list.Insert(1, 7.0); // successful Number of nodes in the list:
list.Insert(2, 5.0); // successful 3
list.Insert(-1, 5.0); // unsuccessful
list.Insert(1, 6.0); // successful
list.Insert(8, 4.0); // unsuccessful
// print all the elements
list.DisplayList();
return 0;
}
42
Using List (2)
Output:
int main(void) 6
{ 7
List list; 5
list.Insert(1, 7.0); // successful Number of nodes in the list:
list.Insert(2, 5.0); // successful 3
5.0 found
list.Insert(-1, 5.0); // unsuccessful
4.5 not found
list.Insert(1, 6.0); // successful
list.Insert(8, 4.0); // unsuccessful
// print all the elements
list.DisplayList();
if(list.Find(5.0) > 0) cout << "5.0 found" << endl;
else cout << "5.0 not found" << endl;
if(list.Find(4.5) > 0) cout << "4.5 found" << endl;
else cout << "4.5 not found" << endl;
return 0;
}
43
Using List
Output:
int main(void) 6
{ 7
List list; 5
list.Insert(1, 7.0); // successful Number of nodes in the list: 3
list.Insert(2, 5.0); // successful 5.0 found
4.5 not found
list.Insert(-1, 5.0); // unsuccessful
6
list.Insert(1, 6.0); // successful 5
list.Insert(8, 4.0); // unsuccessful Number of nodes in the
// print all the elements list: 2
list.DisplayList();
if(list.Find(5.0) > 0) cout << "5.0 found" << endl;
else cout << "5.0 not found" << endl;
if(list.Find(4.5) > 0) cout << "4.5 found" << endl;
else cout << "4.5 not found" << endl;
list.Delete(7.0);
list.DisplayList();
return 0;
}
44
Any Question So Far?
45