import java.applet.Applet;
import java.awt.*;
import java.util.Random;

public class Sorts extends Applet 
  {
    static int N = 10000;
    static int dotsize = 4;
    static Graphics g;

    static void clear(Color c)
      { 
        int h = g.getClipRect().height;
        int w = g.getClipRect().width;
        g.setColor(c);
        g.fillRect(0, 0, w, h);
      }
    static void paint(int i, double x, Color c)
      { 
        int h = g.getClipRect().height;
        int w = g.getClipRect().width;
        g.setColor(c);
        g.fillOval( (i*w)/N, h - (int) (x*h), dotsize, dotsize);
      }
    static void exch(double [] a, int i, int j)
      { double t = a[i]; a[i] = a[j]; a[j] = t;
        paint(i, a[j], Color.white);
        paint(j, a[i], Color.white);
        paint(i, a[i], Color.black);
        paint(j, a[j], Color.black);
      }
    static boolean less(double [] a, int i, int j)
      { 
        paint(i, a[i], Color.red);
        paint(j, a[j], Color.red);
        return a[i] < a[j];
      }
    static int partition(double[] a, int l, int r)
      { int i = l-1, j = r; double t, v = a[r];
        for (;;)
          { 
            while (a[++i] < v) ;
            while (v < a[--j]) if (j == l) break;
            if (i >= j) break;
            exch(a, i, j);
          }
        exch(a, i, r);
        return i;
      }
    static void quicksort(double[] a, int l, int r)
      { int i;
        if (r <= l) return;
        i = partition(a, l, r);
        quicksort(a, l, i-1);
        quicksort(a, i+1, r);
      }
    static void insertion(double a[], int l, int r)
      { int i, j; 
        for (i = l+1; i <= r; i++)
          for (j = i; j > l; j--) 
            if (less(a, j, j-1)) exch(a, j-1, j);
      }
    static void selection(double a[], int l, int r)
      { int i, j; 
        for (i = l; i <= r; i++)
          { int min = i;
            for (j = i+1; j <= r; j++) 
              if (less(a, j, min)) min = j;
            exch(a, i, min);
          }
      }
    static void bubble(double a[], int l, int r)
      { int i, j; 
        for (i = l; i <= r; i++)
          for (j = r; j > i; j--) 
            if (less(a, j, j-1)) exch(a, j-1, j);
      }
    static void shell(double a[], int l, int r)
      { int i, j, h; 
        for (h = 1; h <= (r-l)/9; h = 3*h+1) ;
        for (; h > 0; h /= 3)
          for (i = l+h; i <= r; i++)
            for (j = i; j >= l+h; j -= h) 
              if (less(a, j, j-h)) exch(a, j-h, j);
      }
    static void arrayInitRand(double a[], int l, int r)
      { int i; 
        for (i = l; i <= r; i++)
          {
            a[i] =  Math.random(); 
            paint(i, a[i], Color.black);
          }
      }
    static void arrayInitRev(double a[], int l, int r)
      { int i; 
        for (i = l; i <= r; i++)
          {
            a[i] =  ((double) (r-i))/((double) (r-l)); 
            paint(i, a[i], Color.black);
          }
      }
    public void paint(Graphics page)
      {
        int alg = Integer.parseInt(getParameter("algorithm"));
        double[] a = new double[N];
        g = page;
        N = Integer.parseInt(getParameter("N"));
        dotsize = Integer.parseInt(getParameter("dotsize"));
        arrayInitRand(a, 0, N-1);
        if (alg == 1)
          insertion(a, 0, N-1);
        if (alg == 2)
          selection(a, 0, N-1);
        if (alg == 3)
          bubble(a, 0, N-1);
        if (alg == 4)
          {
            shell(a, 0, N-1);
            clear(Color.lightGray); arrayInitRev(a, 0, N-1);
            shell(a, 0, N-1);
          }
        if (alg == 6)
          quicksort(a, 0, N-1);
        if (alg == 10)
          {
            insertion(a, 0, N-1);
            clear(Color.lightGray); arrayInitRand(a, 0, N-1);
            selection(a, 0, N-1);
            clear(Color.lightGray); arrayInitRand(a, 0, N-1);
            bubble(a, 0, N-1);
            clear(Color.lightGray); arrayInitRand(a, 0, N-1);
            shell(a, 0, N-1);
            clear(Color.lightGray); arrayInitRev(a, 0, N-1);
            insertion(a, 0, N-1);
            clear(Color.lightGray); arrayInitRev(a, 0, N-1);
            selection(a, 0, N-1);
            clear(Color.lightGray); arrayInitRev(a, 0, N-1);
            bubble(a, 0, N-1);
            clear(Color.lightGray); arrayInitRev(a, 0, N-1);
            shell(a, 0, N-1);
          }
      }
  }

