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