program tri_matrice
  implicit none
  integer, parameter   :: n=10, m=3
  real, dimension(n,m) :: mat
  integer              :: ios
  integer              :: i, j
            ! Lecture de la matrice à trier.
  open( unit=1,              &
        file="exo6.matrice", &
        form="unformatted",  &
        status="old",        &
        action="read",       &
        position="rewind",   &
        iostat=ios )
  if ( ios /= 0 ) stop "Erreur à l'ouverture du fichier &
                     &""exo6.matrice"""
  read( unit=1 ) mat; close( unit=1 )
  call tri( mat, n, m ) ! Tri de la matrice lue.
             ! Écriture de la matrice triée.
  open( unit=1,           file="exo11.matrice_triee", &
        form="formatted", status="replace",           &
        action="write",   position="rewind",          &
        iostat=ios )
  if ( ios /= 0 ) stop "Erreur à l'ouverture du fichier &
                     &""exo11.matrice_triee"""
  do i=1,n
    write( unit=1, fmt='(3F7.3)' ) mat(i,:)
  end do
  close( unit=1 )
end program tri_matrice

                   ! Procédure de tri.
subroutine tri( mat, n, m )
  implicit none
  integer              :: n, m
  real, dimension(n,m) :: mat
  integer              :: ligne, col

  do ligne=1,n      ! Tri des lignes.
    call tri_vecteur( mat(ligne,:), m )
  end do
  do col=1,m        ! Tri des colonnes.
    call tri_vecteur( mat(:,col), n )
  end do
  contains
              ! Procédure de tri d'un vecteur.
  subroutine tri_vecteur( v, n )
    integer            :: n, i
    real, dimension(n) :: v
    logical            :: tri_termine
    do
     tri_termine = .true.
     do i=2,n
       if ( v(i) > v(i-1) ) then
         tri_termine = .false.
         ! Utilisation de sections régulières pour
         ! effectuer l'interversion.
         v(i-1:i) = v(i:i-1:-1)
       end if
     end do
     if (tri_termine) exit
    end do
  end subroutine tri_vecteur
end subroutine tri

