Dynamic
Data Structures
Point to Derived Data
Values
•
So
far, we saw examples where pointers pointed to targets that are simple or array
variables
•
Targets
can be of arbitrary types
•
It
becomes interesting when targets are of derived types
•
Suppose
Cricketer is a derived data type. Then
Type(Cricketer), pointer:: cri_p
declares pointer variable cri_p that
points to an instance of type Cricketer
Referring to cri_p
• A new instance of the structure
Cricketer can be created using
– allocate(cri_p,stat=pt_stat)
• The fields can be referred as usual:
– cri_p%name, cri_p%country
• As before, if it appears on the lhs
then the field is updated
– cri_p%name = "Tendulkar“
• If it appears on ths rhs, value stored
in the field is referred
– cntry = cri_p%country
Pointers can be components
• One of the components can be of pointer type!
• This pointer can point to an object of the same type or a
different type
Example:
type::
list
integer:: info
type(list), pointer:: next
end
• The component info contains some integer value
• The second component is a pointer to a similar structure
• using this structure, we can build dynamic data structures
• Lists or Linked lists
Lists
Building Linked lists
• Given a set of N values build a linked
list that store these N items
• This list can later be accessed for
extracting the stored items
• Compare and contrast this with arrays
• The size of the list need not be known
a priori
• The list can grow or shrink dynamically
• Efficient Utilization of Space
• Accessing an item requires some amount
of effort
Program Build_list
Type:: list
integer:: info
type(list), pointer:: next
end type
type(list), pointer:: head, current, prev
integer:: value, N
integer:: l_stat, i
read *, N
nullify(head)
if (N > 0) then
allocate(head, stat=l_stat)
read *, value
head%info = value
prev => head
do i = 2, N
allocate(current, stat=l_stat)
prev%next => current
read *, value
current%info = value
prev => current
end do
nullify(prev%next)
endif
Printing the values in the list
subroutine print_list(head)
implicit none
type(list), pointer:: head
type(list), pointer:: current
current => head
do
if (.not.
(associated(current))) exit
print *, current%info
current =>
current%next
end do
end subroutine
Pointers in subprograms
• Actual pointer argument should match the
type, kind and rank of the dummy argument
• Pointer dummy argument can not have
INTENT attribute
• Procedures with pointer or target dummy
arguments must have an explicit interface
• Declare a module in which include the
type declaration and all the procedures
• More on this later
Accessing an element in the list
subroutine find(head,
val)
type(list), pointer:: head
integer:: val, i
type(list), pointer:: current
current => head
i = 1
do
if (.not. (associated(current))) then
print *, "item not
found"
elseif (current%info == val) then
print *, val, " found at
", i
else
current => current%next
i = i + 1
endif
end do
end subroutine
Inserting an element
subroutine insert_next(p, val)
type(list), pointer:: p
integer:: val, i, istat
type(list), pointer:: temp
allocate(temp, stat = istat)
temp%info = val
temp%next => p%next
p%next => temp
end subroutine
Deleting an element
subroutine delete(p,
head)
type(list), pointer::
p, head, current, prev
current => head
do
if (.not. associated(p)) exit
if (.not. associated(current)) exit
if (.not. associated(current, p)) then
prev => current
current => current%next
else
if (associated(current, head)) then
head => head%next
else
prev%next => current%next
endif
exit
endif
end do
end subroutine
Other Dynamic Data Structures
Doubly Linked lists
– Forward and Backward Traversal possible
Stacks
– Insertion and Deletion from one end
Queues
– Insertion from front end and deletion
from the back
Trees
– Root, Leaf and Intermediate nodes
Graphs