Data Structure and Algorithm (CS 102) : Ashok K Turuk
Data Structure and Algorithm (CS 102) : Ashok K Turuk
Algorithm
(CS 102)
Ashok K Turuk
Problem With Array
• Fixed Length (Occupy a Block of
memory) [Are also called Dense List]
• To expand an Array
– create a new array, longer in size and
– copy the contents of the old array into the
new array
• Insertion or Deletion
2
Solution
• Attach a pointer to each item in
the array, which points to the
next item
4
Linked List
• Each node is divided into two
parts
– First part contains the information
of the element, and
– Second part called the link field or
nextpointer field contains the
address of the next node in the list.
5
Linked Lists
A B C
Head
• A linked list is a series of connected
nodes
• Head : pointer to the first node
• The last node points to NULL
6
Linked Lists
node
A
data pointer
7
A Simple Linked List Class
• 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
};
A Simple Linked List Class
newNode
Inserting a new node
int currIndex = 1;
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
currIndex++;
}
if (index > 0 && currNode == NULL) return NULL;
int currIndex = 1;
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
}
currIndex++;
Insert as first
element
if (index > 0 && currNode == NULL) return NULL;
if (index == 0) {
newNode->next = head; head
head = newNode;
}
else {
newNode->next = currNode->next;
currNode->next = newNode;
} newNode
return newNode;
}
Inserting a new node
Node* List::InsertNode(int index, double x) {
if (index < 0) return NULL;
int currIndex = 1;
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
currIndex++;
}
if (index > 0 && currNode == NULL) return NULL;
Insert after
Node* newNode = new Node;
newNode->data = x;
if (index == 0) {
newNode->next
head =
= head;
newNode; currNode
}
else {
newNode->next =currNode->next;
currNode->next = newNode;
} currNode
return newNode;
} newNode
Finding a node
• int FindNode(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::FindNode(double x) {
Node* currNode = head;
int currIndex = 1;
while (currNode && currNode->data != x) {
currNode = currNode->next;
currIndex++;
}
if (currNode) return currIndex;
return 0;
}
Finding a node
• int FindNode(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::FindNode(double x) {
Node* currNode = head;
int currIndex= 1;
while (currNode && currNode->data != x) {
currNode =currNode->next;
currIndex++;
}
if (currNode) return currIndex;
return 0;
}
Deleting a node
• int DeleteNode(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 FindNode)
– Release the memory occupied by the found node
– Set the pointer of the predecessor of the found node to the successor of the found node
• Like InsertNode, there are two special cases
– Delete first node
– Delete the node in middle or at the end of the list
Deleting a node
• int DeleteNode(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
FindNode)
– Release the memory occupied by the
found node
– Set the pointer of the predecessor
of the found node to the successor
of the found node
• Like InsertNode, there are two special cases
– Delete first node
– Delete the node in middle or at the end of the list
Deleting a node
• int DeleteNode(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 FindNode)
– Release the memory occupied by the found node
– Set the pointer of the predecessor of the found node to the successor of the found node
prevNode currNode
A B C
Deleting a node
int List::DeleteNode(double x) {
prevNode
A C
Deleting a node
int List::DeleteNode(double x) {
prevNode
A C
Deleting a node
int List::DeleteNode(double x) {
Node* prevNode = NULL;
Node* currNode = head;
int currIndex = 1;
while (currNode && currNode->data != x) {
prevNode = currNode;
currNode= currNode->next;
currIndex++;
}
if (currNode) {
if (prevNode) {
prevNode->next= currNode-
>next;
delete currNode;
}
else {
head = currNode->next;
delete currNode;
}
return currIndex;
}
return 0;
}
Deleting a node
int List::DeleteNode(double x) {
head currNode
A B
Deleting a node
int List::DeleteNode(double x) {
head
B
Deleting a node
int List::DeleteNode(double x) {
head
B
Deleting a node
int List::DeleteNode(double x) {
Node* prevNode = NULL;
Node* currNode = head;
int currIndex = 1;
while (currNode && currNode->data != x) {
prevNode = currNode;
currNode= currNode->next;
currIndex++;
}
if (currNode) {
if (prevNode) {
prevNode->next = currNode->next;
delete currNode;
}
else {
head= currNode->next;
delete currNode;
}
return currIndex;
}
return 0;
}
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* currNode = head;
while (currNode != NULL){
cout << currNode->data << endl;
currNode = currNode->next;
num++;
}
cout << "Number of nodes in the list: " << num << endl;
}
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* currNode = head, *nextNode = NULL;
while (currNode != NULL)
{
nextNode = currNode->next;
// destroy the current node
delete currNode;
currNode = nextNode;
}
}
6 result
Using List
7
5
Number of nodes in the list: 3
5.0 found
4.5 not found
6
5
int main(void) Number of nodes in the list: 2
{
List list;
list.InsertNode(0, 7.0); // successful
list.InsertNode(1, 5.0); // successful
list.InsertNode(-1, 5.0); // unsuccessful
list.InsertNode(0, 6.0); // successful
list.InsertNode(8, 4.0); // unsuccessful
// print all the elements
list.DisplayList();
if(list.FindNode(5.0) > 0) cout << "5.0 found" << endl;
else cout << "5.0 not found" << endl;
if(list.FindNode(4.5) > 0) cout << "4.5 found" << endl;
else cout << "4.5 not found" << endl;
list.DeleteNode(7.0);
list.DisplayList();
return 0;
}
Variations of Linked Lists
• Circular linked lists
– The last node points to the first node of the list
A B C
Head
A B C
Head
Time of the Operations
• Time to search() is O(L) where L is the
relative location of the desired item in the
List. In the worst case. The time is O(n). In
the average case it is O(N/2)=O(n).
• Time for remove() is dominated by the time
for search, and is thus O(n).
• Time for insert at head or at tail is O(1).
• Time for insert at other positions is
dominated by search time, and thus O(n).
• Time for size() is O(1), and time for isEmpty() is O(1)
CS 103 38