FWIW, here's a solution using a tree. No attempt to balance it.
module treemodule
implicit none
private
public numDistinct
type Node
integer value
type(Node), pointer :: left => null(), right => null()
end type node
type, public :: Tree
private
type(Node), pointer :: root => null()
integer :: size = 0
contains
procedure insert
procedure clear
procedure print
procedure getsize
procedure, private :: insertNode
procedure, private :: deleteNode
procedure, private :: printNode
end type Tree
contains
integer function numDistinct( A )
integer, intent(in) :: A(:)
integer i
type(Tree) T
numDistinct = 3
do i = 1, size( A )
call T%insert( A(i) )
end do
numDistinct = T%getsize()
! Comment out the following if you don't need it ...
write( *, "(A)", advance="no" ) "Distinct elements: "; call T%print; write( *, * )
call T%clear
end function numDistinct
integer function getsize( this )
class(Tree) this
getsize = this%size
end function getsize
subroutine insert( this, value )
class(Tree) this
integer, intent(in) :: value
call this%insertNode( this%root, value )
end subroutine insert
subroutine print( this )
class(Tree) this
call this%printNode( this%root )
end subroutine print
subroutine clear( this )
class(Tree) this
call this%deleteNode( this%root )
end subroutine clear
recursive subroutine insertNode( this, ptr, value )
class(Tree) this
type(Node), pointer, intent(inout) :: ptr
integer value
if ( associated( ptr ) ) then
if ( value < ptr%value ) then
call this%insertNode( ptr%left, value )
else if ( value > ptr%value ) then
call this%insertNode( ptr%right, value )
end if
else
allocate( ptr, source=Node(value) )
this%size = this%size + 1
end if
end subroutine insertNode
recursive subroutine deleteNode( this, ptr )
class(Tree) this
type(Node), pointer, intent(inout) :: ptr
if ( associated( ptr ) ) then
call this%deleteNode( ptr%left )
call this%deleteNode( ptr%right )
deallocate( ptr )
this%size = this%size - 1
end if
end subroutine deleteNode
recursive subroutine printNode( this, ptr )
class(Tree) this
type(Node), pointer, intent(in) :: ptr
if ( associated( ptr ) ) then
call this%printNode( ptr%left )
write ( *, "( i0, 1x )", advance="no" ) ptr%value
call this%printNode( ptr%right )
end if
end subroutine printNode
end module treemodule
!=======================================================================
program main
use treemodule
implicit none
integer, allocatable :: A(:)
integer C
A = [ 0, 5, 1, 8, 9, 1, 1 ]
C = numDistinct( A )
write( *, "( 'Number of distinct elements = ', i0 )" ) C
end program main
Distinct elements: 0 1 5 8 9
Number of distinct elements = 5