Linked lists are a fundamental data structure in computer science, used to store a collection of elements. Unlike arrays, linked lists allow for efficient insertion and deletion of elements. In Fortran, linked lists can be implemented using derived types and pointers.
Key Concepts
- Node Structure: Each element in a linked list is called a node. A node contains data and a pointer to the next node.
- Head Pointer: A pointer that points to the first node in the linked list.
- Traversal: The process of visiting each node in the linked list.
- Insertion: Adding a new node to the linked list.
- Deletion: Removing a node from the linked list.
Node Structure
In Fortran, we define a node using a derived type. Each node will contain an integer data field and a pointer to the next node.
Head Pointer
The head pointer is a pointer to the first node in the linked list. Initially, it is set to null().
Traversal
Traversal involves visiting each node in the linked list. We start from the head and follow the next pointers until we reach the end of the list.
subroutine traverse(head)
type(Node), pointer :: head, current
current => head
do while (associated(current))
print *, current%data
current => current%next
end do
end subroutine traverseInsertion
Inserting at the Beginning
To insert a new node at the beginning of the linked list, we create a new node and set its next pointer to the current head. Then, we update the head to point to the new node.
subroutine insert_at_beginning(head, value)
type(Node), pointer :: head, new_node
integer :: value
allocate(new_node)
new_node%data = value
new_node%next => head
head => new_node
end subroutine insert_at_beginningInserting at the End
To insert a new node at the end of the linked list, we traverse to the last node and set its next pointer to the new node.
subroutine insert_at_end(head, value)
type(Node), pointer :: head, new_node, current
integer :: value
allocate(new_node)
new_node%data = value
new_node%next => null()
if (.not. associated(head)) then
head => new_node
else
current => head
do while (associated(current%next))
current => current%next
end do
current%next => new_node
end if
end subroutine insert_at_endDeletion
Deleting a Node
To delete a node, we need to find the node to be deleted and update the next pointer of the previous node to skip the deleted node.
subroutine delete_node(head, value)
type(Node), pointer :: head, current, previous
integer :: value
current => head
previous => null()
do while (associated(current) .and. current%data /= value)
previous => current
current => current%next
end do
if (associated(current)) then
if (associated(previous)) then
previous%next => current%next
else
head => current%next
end if
deallocate(current)
end if
end subroutine delete_nodePractical Exercise
Exercise: Implement a Linked List
- Define a derived type
Nodewith an integer data field and a pointer to the next node. - Write a subroutine
insert_at_beginningto insert a new node at the beginning of the linked list. - Write a subroutine
insert_at_endto insert a new node at the end of the linked list. - Write a subroutine
delete_nodeto delete a node with a given value. - Write a subroutine
traverseto print all the elements in the linked list.
Solution
module linked_list_module
implicit none
type :: Node
integer :: data
type(Node), pointer :: next => null()
end type Node
contains
subroutine insert_at_beginning(head, value)
type(Node), pointer :: head, new_node
integer :: value
allocate(new_node)
new_node%data = value
new_node%next => head
head => new_node
end subroutine insert_at_beginning
subroutine insert_at_end(head, value)
type(Node), pointer :: head, new_node, current
integer :: value
allocate(new_node)
new_node%data = value
new_node%next => null()
if (.not. associated(head)) then
head => new_node
else
current => head
do while (associated(current%next))
current => current%next
end do
current%next => new_node
end if
end subroutine insert_at_end
subroutine delete_node(head, value)
type(Node), pointer :: head, current, previous
integer :: value
current => head
previous => null()
do while (associated(current) .and. current%data /= value)
previous => current
current => current%next
end do
if (associated(current)) then
if (associated(previous)) then
previous%next => current%next
else
head => current%next
end if
deallocate(current)
end if
end subroutine delete_node
subroutine traverse(head)
type(Node), pointer :: head, current
current => head
do while (associated(current))
print *, current%data
current => current%next
end do
end subroutine traverse
end module linked_list_module
program test_linked_list
use linked_list_module
implicit none
type(Node), pointer :: head => null()
call insert_at_beginning(head, 10)
call insert_at_beginning(head, 20)
call insert_at_end(head, 30)
call traverse(head)
call delete_node(head, 20)
call traverse(head)
end program test_linked_listSummary
In this section, we covered the basics of linked lists in Fortran, including:
- Defining a node structure using derived types.
- Implementing head pointers.
- Traversing the linked list.
- Inserting nodes at the beginning and end of the list.
- Deleting nodes from the list.
Understanding linked lists is crucial for mastering more complex data structures and algorithms. In the next module, we will explore file handling in Fortran, which is essential for reading and writing data to files.
Fortran Programming Course
Module 1: Introduction to Fortran
- Introduction to Fortran
- Setting Up the Development Environment
- Basic Syntax and Structure
- Writing Your First Fortran Program
Module 2: Basic Concepts
- Variables and Data Types
- Operators and Expressions
- Input and Output
- Control Structures: If Statements
- Control Structures: Loops
Module 3: Arrays and Strings
Module 4: Procedures and Functions
Module 5: Advanced Data Structures
Module 6: File Handling
Module 7: Advanced Topics
Module 8: Best Practices and Optimization
- Code Optimization Techniques
- Debugging and Profiling
- Writing Maintainable Code
- Fortran Standards and Portability
