// file:    minsort.java
// author:  Robert Keller
// purpose: illustrating a simple sorting program

import java.lang.*;
import java.io.*;
import java.util.*;

class minsort
  {
  private double array[];	// The array being sorted

  /**
    *  Calling minsort constructor on array of doubles sorts the array.
    *  Parameter N is the number of elements to be sorted.
   **/

  minsort(double array[], int N)
    {
    this.array = array;

    for( int i = 0; i < N; i++ )
      {
      swap(i, findMin(i, N));
      }
    }


  /**
    *  swap(i, j) interchanges the values in array[i] and array[j]
   **/

  void swap(int i, int j)
    {
    double temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }


  /**
    *  findMin(M, N) finds the index of the minimum among
    *  array[M], array[M+1], ...., array[N-1].
   **/

  int findMin(int minSoFar, int N)
    {
    // by default, the element at minSoFar is the minimum

    for( int j = minSoFar+1; j < N; j++ )
      {
      if( array[j] < array[minSoFar] )
        {
        minSoFar = j;	// a smaller value is found
        }
      }
    return minSoFar;
    }


  /**
    *  test program for minsort; reads arbitrarily-many numbers 
    *  from standard input, sorts them, then writes them to standard output.
   **/

  public static void main(String[] args)
    {
    StreamTokenizer in = new StreamTokenizer(System.in);

    int Size = 1;			// initial allocation
    int N = 0;				// number of elements in array
    double array[] = new double[Size];	// initial array allocation

    try
      {
      // while more numbers in file
      while( in.nextToken() != java.io.StreamTokenizer.TT_EOF )	
	{
	if( N == Size )			// if the array is full
	  {
	  array = reallocate(array);    // double the array size
	  Size *= 2;	
	  }
	array[N++] = in.nval;		// put item in array
	}
      }
    catch(IOException e)
      {
      System.err.println("*** IOException caught");
      }

    Date startTime = new Date();

    System.err.println("Sorting started");

    new minsort(array, N);		// calling constructor sorts

    Date endTime = new Date();

    long time = endTime.getTime() - startTime.getTime();

    System.err.println("Sorting finished in " + time + " ms");

    for( int i = 0; i < N; i++ )
      {
      System.out.print(array[i] + " ");
      }    

    System.out.println();

    System.err.println("Sorting " + N + " elements using minsort took " + 
                        time + " ms");
    }


  /**
    *  reallocate allocates a new array double the size of the original
    *  and copies the original into it.  The new array is returned.
   **/

  static double[] reallocate(double array[])
    {
    double[] newArray = new double[2*array.length];
    for( int i = 0; i < array.length; i++ )		// copy old array
      newArray[i] = array[i];    
    return newArray;
    }
  }
