0% found this document useful (0 votes)
31 views6 pages

bcp121 Week 11 Module

This Week 11 learning module for bcp121 focuses on the Introduction to Singly Linked Lists in C++. It covers the limitations of arrays, the structure and management of linked lists, and includes practical coding exercises for insertion, deletion, and traversal of nodes. Students will also learn about dynamic memory management and the advantages and disadvantages of linked lists compared to arrays.
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)
31 views6 pages

bcp121 Week 11 Module

This Week 11 learning module for bcp121 focuses on the Introduction to Singly Linked Lists in C++. It covers the limitations of arrays, the structure and management of linked lists, and includes practical coding exercises for insertion, deletion, and traversal of nodes. Students will also learn about dynamic memory management and the advantages and disadvantages of linked lists compared to arrays.
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/ 6

Okay, here is a student-facing learning module for Week 11 of bcp121 (Computer

Programming in Technology 2 - C++), focusing on Introduction to Singly Linked Lists. This


module is designed for students in Surigao City, Philippines, reflecting the current date context
(April 5th, 2025, meaning Week 11 starts around April 7th).
[Your Institution Name] [Your Department Name] Course Code: bcp121 Course Title:
Computer Programming in Technology 2
Week 11 Learning Module: Introduction to Singly Linked Lists
Date: Week of April 7th, 2025
I. Introduction
Welcome to Week 11! So far in our C++ journey, we've worked extensively with fundamental
data types and built-in structures like arrays. Arrays are powerful, but they have limitations,
especially when we don't know how much data we'll need beforehand or if we need to frequently
insert or remove items.
This week, we dive into our first major dynamic data structure: the Linked List. Linked lists
provide a flexible way to store a collection of items that can easily grow or shrink. We will focus
on the simplest type: the Singly Linked List. Understanding linked lists is crucial as they form
the basis for many other important data structures and algorithms you'll encounter.
II. Learning Objectives
By the end of this module and the related lab activities, you should be able to:
1.​ Explain why dynamic data structures like linked lists are needed (limitations of arrays).
2.​ Describe the core concept of a linked list: nodes containing data and a pointer to the next
node.
3.​ Define a Node structure in C++ suitable for a singly linked list.
4.​ Illustrate how a linked list is managed using a head pointer and how nullptr signifies the
end.
5.​ Write C++ code to traverse a singly linked list from head to tail.
6.​ Implement algorithms (with code snippets) for inserting new nodes at the beginning
(head) and end (tail) of a list.
7.​ Implement algorithms (with code snippets) for deleting nodes from the beginning (head)
and end (tail) of a list.
8.​ Explain the critical role of new and delete for memory management in linked lists.
9.​ Compare the basic performance characteristics (efficiency) of linked lists vs. arrays for
common operations.
III. Key Concepts (Reading & Explanation)
A. Why Linked Lists? The Limits of Arrays
Remember arrays? They store elements side-by-side in memory. This gives them one big
advantage:
●​ Fast Random Access: You can jump directly to any element using its index (e.g.,
myArray[5]) in constant time, O(1).
But they also have significant drawbacks:
●​ Fixed Size: Once you declare an array's size (or allocate it dynamically), changing that
size later is inefficient. You typically have to create a completely new, larger array and
copy all the old elements over.
●​ Inefficient Insertions/Deletions: If you want to insert or delete an element in the middle
of an array, you have to shift all the subsequent elements up or down, which takes linear
time, O(n).
Linked lists offer solutions to these specific problems.
B. The Linked List Concept
Imagine a chain of nodes, like cars in a train or clues in a treasure hunt. Each node in a linked
list contains two key pieces of information:
1.​ The Data: The actual value or object we want to store (e.g., an integer, a string, a student
record).
2.​ A Pointer (Link): An address that points to the next node in the sequence.
Diagram:
+------+------+ +------+------+ +------+------+​
| Data | Next | --> | Data | Next | --> | Data | Next | --> NULL​
+------+------+ +------+------+ +------+------+​
Node 1 Node 2 Node 3​

The nodes themselves might be scattered randomly in computer memory, unlike array
elements. The pointers are what hold the list together in the correct order. The last node's next
pointer points to nullptr (or NULL in older C/C++), indicating the end of the list.
C. The Node Structure in C++
We typically define a structure (or class) to represent a node. A common way using a struct is:
#include <iostream> // For std::cout in constructor/destructor example​

template<typename T> // Often templated to hold any data type​
struct Node {​
T data; // The data stored in the node​
Node* next; // Pointer to the next Node in the list​

// Constructor to initialize a node​
Node(T val) : data(val), next(nullptr) {​
// std::cout << "Node(" << data << ") created.\n"; // Useful
for debugging​
}​

// Destructor (useful for debugging memory leaks)​
~Node() {​
// std::cout << "Node(" << data << ") destroyed.\n";​
}​
};​

Key Point: Notice that Node* next; is a pointer to another Node. This self-referential structure is
what allows nodes to link together. We often make the Node a template so the list can hold data
of any type (int, double, string, custom objects, etc.).
D. Representing the List: The head Pointer
How do we keep track of the whole list? We only need one pointer: a pointer to the very first
node. This is traditionally called the head pointer.
Node<int>* head = nullptr; // Pointer to the first node. Initially
null for an empty list.​

●​ If head is nullptr, the list is empty.


●​ If the list is not empty, head points to the first node. You access the rest of the list by
following the next pointers from the head.
Diagram:
head​
|​
V​
+------+------+ +------+------+​
| 10 | Next | --> | 20 | Next | --> nullptr​
+------+------+ +------+------+​

E. Traversing the List


To visit every node (e.g., to print their data), you start at the head and follow the next pointers
until you reach nullptr.
Algorithm:
1.​ Create a temporary pointer current and initialize it to head.
2.​ While current is not nullptr: a. Process the data at the current node (e.g., current->data).
b. Move current to the next node: current = current->next;
C++ Snippet (Printing data):
void printList(Node<int>* head) {​
Node<int>* current = head;​
while (current != nullptr) {​
std::cout << current->data << " -> ";​
current = current->next; // Move to the next node​
}​
std::cout << "nullptr" << std::endl;​
}​

Visual Trace: Draw a list and manually step through the traversal, showing how the current
pointer moves from node to node.
F. Insertion Operations
Nodes are created dynamically on the heap using new.
●​ Insertion at Head (Prepend) - O(1) Efficiency:
1.​ Create the newNode with the desired data: Node<T>* newNode = new
Node<T>(value);
2.​ Set the newNode's next pointer to point to the current head node: newNode->next =
head;
3.​ Update the head pointer to point to the newNode: head = newNode;
○​ Diagram: Show how the new node slots in before the old head. Handle the empty
list case (where head was initially nullptr).
●​ Insertion at Tail (Append) - O(n) Efficiency (Basic version):
1.​ Create the newNode: Node<T>* newNode = new Node<T>(value); (Its next is
already nullptr).
2.​ If list is empty (head == nullptr): Set head = newNode; and you're done.
3.​ If list is not empty: Traverse the list until you find the last node (the one whose
next is nullptr).​
Node<T>* temp = head;​
while (temp->next != nullptr) {​
temp = temp->next; // Move temp until it points to the
last node​
}​
4.​ Link the last node to the new node: temp->next = newNode;
○​ Diagram: Show the traversal to the end and linking the new node. Note the time
taken depends on the list length (O(n)).
G. Deletion Operations
Memory used by deleted nodes must be freed using delete.
●​ Deletion from Head - O(1) Efficiency:
1.​ If list is empty (head == nullptr): Nothing to delete.
2.​ Store the node to be deleted in a temporary pointer: Node<T>* nodeToDelete =
head;
3.​ Update head to point to the next node: head = head->next; (or head =
nodeToDelete->next;)
4.​ Crucially, free the memory: delete nodeToDelete;
○​ Diagram: Show head moving forward and the old head node being deleted. Handle
the case where you delete the only node in the list (head becomes nullptr).
●​ Deletion from Tail - O(n) Efficiency (Basic version):
1.​ Handle Empty List: If head == nullptr, return.
2.​ Handle Single Node List: If head->next == nullptr, delete head; head = nullptr;
return.
3.​ Traverse to find the second-to-last node: Need two pointers, current and
previous.​
Node<T>* current = head;​
Node<T>* previous = nullptr; // Or Node<T>* previous = head;
and start current at head->next if list has >1 node​
while (current->next != nullptr) { // Stop when current IS
the last node​
previous = current;​
current = current->next;​
}​

4.​ Unlink the last node by setting the next of the second-to-last node to nullptr:
previous->next = nullptr;
5.​ Free the memory: delete current; (delete the original last node).
○​ Diagram: Show the two pointers traversing, the unlinking step, and the deletion.
H. Dynamic Memory Management (new/delete)
●​ new Node<T>(...) allocates memory on the heap for a node. This memory persists until
explicitly freed.
●​ delete nodePointer; frees the memory pointed to by nodePointer.
●​ Memory Leaks: If you remove a node from the list (by changing pointers) but forget to
delete it, that memory becomes inaccessible but still allocated – a memory leak. Over
time, leaks consume system memory.
●​ Dangling Pointers: After delete nodePointer;, the nodePointer itself still holds the old
address (now invalid). Accessing it leads to undefined behavior. Set deleted pointers to
nullptr: nodePointer = nullptr; (good practice).
●​ Responsibility: When using linked lists, you are responsible for managing the memory of
each node. A well-designed LinkedList class will handle deletion in its destructor.
I. Advantages & Disadvantages Summary
●​ Linked Lists:
○​ Pros: Dynamic size (grow/shrink easily), Efficient insertion/deletion at known
locations (especially head, O(1)), Uses memory as needed.
○​ Cons: Linear time access to elements (O(n) - no indexing like list[i]), Less
cache-friendly than arrays, Extra memory required for pointers, Tail operations can
be slow (O(n)) without optimizations (like a tail pointer).
●​ Arrays:
○​ Pros: Fast random access by index (O(1)), More cache-friendly (contiguous
memory).
○​ Cons: Fixed size (resizing is O(n)), Inefficient insertion/deletion in the middle (O(n)).
VI. Laboratory Activities Guide (Summary)
This week's lab will involve hands-on implementation of the concepts covered:
1.​ Define the Node struct in C++.
2.​ Manual List Creation: Practice using new to create nodes and manually link them
together using a head pointer.
3.​ Traversal Function: Implement and test a function to print the data in your manually
created list.
4.​ Insertion Functions: Implement and test functions for insertAtHead and insertAtTail.
5.​ Deletion Functions: Implement and test functions for deleteFromHead and
deleteFromTail.
6.​ Testing: Create various scenarios (empty list, single node, multiple nodes) to test your
functions thoroughly. Pay attention to pointer updates and use delete.
VII. Key Terms
●​ Linked List: A linear data structure where elements (nodes) are linked by pointers.
●​ Singly Linked List: Each node points only to the next node in the sequence.
●​ Node: An element in a linked list, containing data and a pointer (next).
●​ Head Pointer: A pointer to the first node in the list. nullptr if the list is empty.
●​ Pointer: A variable storing a memory address.
●​ Dynamic Memory Allocation: Allocating memory during program execution (on the
heap) using new.
●​ new: C++ operator to allocate memory on the heap.
●​ delete: C++ operator to free memory allocated with new.
●​ nullptr: A keyword representing a null pointer (points to nothing).
●​ Traversal: Visiting each node in the list, usually starting from the head.
●​ Insertion: Adding a new node to the list.
●​ Deletion: Removing a node from the list and freeing its memory.
●​ Memory Leak: Allocated memory that is no longer accessible but has not been freed with
delete.
VIII. Review Questions (Self-Check)
1.​ What are the two main components of a node in a singly linked list?
2.​ How do you represent an empty linked list?
3.​ Describe the steps involved in traversing a linked list to print all data elements.
4.​ What are the three main steps to insert a new node at the head of a linked list?
5.​ Why is deleting from the tail of a basic singly linked list typically an O(n) operation?
6.​ What C++ keyword is used to allocate memory for a new node? What keyword is used to
free it?
7.​ What happens if you forget to delete a node after removing it from the list pointers?
IX. Next Steps
Now that you understand the fundamental mechanics of singly linked lists, we will move on to:
●​ Encapsulating these operations within a LinkedList class.
●​ Implementing insertion and deletion at specific positions within the list.
●​ Exploring other list types like Doubly Linked Lists and Circular Linked Lists.
●​ Seeing how linked lists are used to build other data structures like Stacks and Queues.
This module provides the necessary conceptual background and prepares students for the
practical implementation tasks in the Week 11 lab session for bcp121 (CPT 102).

You might also like