W9 Linked List(1)
W9 Linked List(1)
Programming
3
Why Learning Linked List?
4
Introduction to Linked List
5
Introduction to Linked List
Deleting a node
6
An Empty Linked List
Make nullptr your default choice for representing null pointers in C++
7
Define a Linked List
• Declare a node:
struct Node
{
double value; //It can be other data types
Node *next;
};
No memory is allocated at this time
• Define a pointer to be used as the list head and initialize it to
nullptr
Node* head = nullptr;
8
Outline
9
Two Common Pointer Bugs in
implementing linked list operations
• Attempting to dereference a pointer via *p or p-> when
p==NULL or p == nullptr
• Attempting to dereference a pointer via *p or p-> when p is
not properly initialized
• NOTE: this error does not cause a syntax error, but instead
causes errors:
- Bus Error
- Segmentation violation
- Address protection violation
10
Add a Node at the End of the List
• Basic process:
– Create the new node
– Add node to the end of the list:
• If list is empty, set head pointer to this node
• Else,
– traverse the list to the end
– set pointer of last node to point to new node
• It is the basic operation for creating a linked list
11
Create a New Node
Node
• Allocate memory for the new node:
Node = new Node;
• Initialize the contents of the node:
Node->value = num; Node
Node->next = nullptr;
Node
num nullptr
12
Add a Node at the End of the List
#include <iostream>
using namespace std;
struct Node {
double value; // Can be any data type
Node* next; 12.5
};
int main() {
Node* head = nullptr; // Create the head pointer
insertNode2ListEnd (head, 12.5);
insertNode2ListEnd (head, 13.5);
cout<<"1st Node: "<< head->value <<endl;
cout<<"2nd Node: "<< head->next->value<<endl;
return 0;
} 13
Add a Node at the End of the List
#include <iostream>
using namespace std;
struct Node {
double value; // Can be any data type
Node* next; 12.5
};
int main() {
Node* head = nullptr; // Create the head pointer
insertNode2ListEnd (head, 12.5);
insertNode2ListEnd (head, 13.5);
cout<<"1st Node: "<< head->value <<endl;
cout<<"2nd Node: "<< head->next->value<<endl;
return 0;
} 14
A Reference to Pointer
• Node*& head vs. Node* head
- A reference to a pointer: Node*& head
- A regular pointer: Node* head
• A reference to a pointer can ensure that any modifications to
head within the function can affect the original linked list
15
A Reference to Pointer vs a Regular
Pointer
#include <iostream>
using namespace std;
void modifyPointer(int* p) {
int x = 10;
p = &x; // This only modifies the local copy of pointer p, not the original pointer p in main
}
Program output:
int main() {
int a = 5; Before modifyPointer: 5
int* ptr = &a; After modifyPointer: 5
a
Addr: 9000 5 Need to use a reference to pointer to change
the content of the original pointer here!
ptr
x
Addr: 7000 9000 Addr: 5000
10
p
Addr: 6000 9000 16
A Reference to Pointer vs a Regular
Pointer
#include <iostream>
using namespace std;
void modifyPointer(int* p) {
int x = 10;
p = &x; // This only modifies the local copy of pointer p, not the original pointer p in main
}
Program output:
int main() {
int a = 5; Before modifyPointer: 5
int* ptr = &a; After modifyPointer: 5
a
Addr: 9000 5 Need to use a reference to pointer to change
the content of the original pointer here!
ptr
x
Addr: 7000 9000 Addr: 5000
10
p
Addr: 6000 9000 17
Delete a Node
18
Delete a Node
void remove(Node*& head, double number) {
• Basic process: Node *nodePtr, *previousNodePtr;
- Locating the node containing if (head == nullptr) return; // If the list is empty
// Determine if the first node is the one to delete
the element to be removed if (fabs(head->value - number) < 1e-9)
{
- Unhooking the node from nodePtr = head;
head = head->next;
the list delete nodePtr;
nodePtr = nullptr;
- Deleting the memory } else
{ // Initialize nodePtr to the list head
allocated to the node nodePtr = head;
// Link the previous node to the node after nodePtr, then delete nodePtr.
if (nodePtr != nullptr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
nodePtr = nullptr;
}
}
}
19
Delete a Node
void remove(Node*& head, double number) {
• Basic process: Node *nodePtr, *previousNodePtr;
// Link the previous node to the node after nodePtr, then delete nodePtr.
if (nodePtr != nullptr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
nodePtr = nullptr;
}
}
}
20
Delete a Node
void remove(Node*& head, double number) {
• Basic process: Node *nodePtr, *previousNodePtr;
// Link the previous node to the node after nodePtr, then delete nodePtr.
if (nodePtr != nullptr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
nodePtr = nullptr;
}
}
}
21
Delete a Node
void remove(Node*& head, double number) {
• Basic process: Node *nodePtr, *previousNodePtr;
// Link the previous node to the node after nodePtr, then delete nodePtr.
if (nodePtr != nullptr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
nodePtr = nullptr;
}
}
}
22
Delete a Node
void remove(Node*& head, double number) {
• Basic process: Node *nodePtr, *previousNodePtr;
// Link the previous node to the node after nodePtr, then delete nodePtr.
if (nodePtr != nullptr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
nodePtr = nullptr;
}
}
}
23
Delete a Node
void remove(Node*& head, double number) {
• Basic process: Node *nodePtr, *previousNodePtr;
// Link the previous node to the node after nodePtr, then delete nodePtr.
if (nodePtr != nullptr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
nodePtr = nullptr;
}
}
}
24
Outline
25
Traverse a Linked List
• Visit each node in a linked list: display contents, validate data,
etc.
• Basic process:
– set a pointer to the contents of the head pointer
– while pointer is not nullptr
• process data
• go to the next node by setting the pointer to the pointer field of the
current node in the list
– end while
nodePtr points to the node containing 2.5, then the node containing 7.9,
then the node containing 12.6, then points to nullptr, and the list
traversal stops
26
Traverse a Linked List
• Example: printList()
• Basic process:
– set a pointer to the contents of the head pointer
– while pointer is not nullptr
• process data
• go to the next node by setting the pointer to the pointer field of the
current node in the list
– end while
27
Traverse a Linked List
void printList(Node* head) {
Node* current = head;// Start at the head of the list
Program output:
28
Traverse a Linked List
void printList(Node* head) {
Node* current = head;// Start at the head of the list
Program output:
2.5 ->
29
Traverse a Linked List
void printList(Node* head) {
Node* current = head;// Start at the head of the list
Program output:
2.5 ->
30
Traverse a Linked List
void printList(Node* head) {
Node* current = head;// Start at the head of the list
Program output:
2.5 ->
31
Traverse a Linked List
void printList(Node* head) {
Node* current = head;// Start at the head of the list
Program output:
2.5 ->
32
Delete/Destroy a Linked List
• The nodes of a linked list are dynamically allocated
• When deleting or destroying a linked list, we must remove all
nodes used in the list, where we need to traverse the linked list
• Basic process:
– set a pointer nodePtr to the contents of the head pointer
– while pointer is not nullptr
• use another pointer garbage to keep track of the node to be deleted
• go to the next node by setting the pointer nodePtr to the pointer field
of the current node in the list
• deallocate the memory of the current node
– end while
33
Delete/Destroy a Linked List
• Basic process:
– set a pointer nodePtr to the contents of the head pointer
– while pointer is not nullptr
• use another pointer garbage to keep track of the node to be deleted
• go to the next node by setting the pointer nodePtr to the pointer field
of the current node in the list
• deallocate the memory of the current node
– end while
nodePtr
35
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
36
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
37
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
38
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
39
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
40
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
41
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
42
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
43
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
44
Delete/Destroy a Linked List
void destroyList(Node*& head)
{
Node *nodePtr = head; // Start at head of list
Node *garbage = nullptr;
while (nodePtr != nullptr)
{
// garbage keeps track of node to be deleted
garbage = nodePtr;
// Move on to the next node, if any
nodePtr = nodePtr->next;
// Delete the "garbage" node
delete garbage;
garbage = nullptr;
}
head = nullptr;
}
nodePtr
garbage
45
Outline
46
Variations of the Linked List
• There are many ways to link dynamically allocated data
structures together. Two variations of the linked list are the
doubly linked list and the circular linked list.
The last node and first node have pointers to the NULL address, which
can be used to check if we have reached either end.
Variations of the Linked List
• Circular linked list: The last node in this type of linked list
points to the first node, not to the NULL address
More about Linked List
• There are other linked list operations, e.g., list copy, list
append, compute the length of a linked list, etc., but the basic
ideas are more or less the same
50
Questions?
Thank You!