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