i have to understand the way this programm works... Having only basic
knowledge of java i would very much appreciate if somebody would help
me by commenting this programm... Lots of thanks!
Stephane
import java.applet.*;
import java.awt.*;
import java.lang.*;
import java.util.*;
// the sort classes: feel free to add your own classes...
// this naive approach is unfortunately frequently used, because
// it works well in some frequently occuring cases: the list
// is almost sorted, and unsorted items are 'below' their final
position.
// (this happens for instance when sorting an array of invoices
// by invoice number, when some invoices have been inserted in 'holes'
// in the initial array.
// use insertion sort instead if you want to be naive, or at least
shaker sort.
class BubbleSort extends AlgoTri {
BubbleSort (int t, VueTris v) { super("Bubble Sort", t, v); }
public void sort () {
boolean dep=false;
int curndx=size;
do {
dep=false;
for (int i=1; i < curndx; i++) {
if (compare(i, i-1)<0) {
exchange(i, i-1);
dep=true;
}
} curndx--;
} while (dep);
}
};
// shaker sort is an optimization of bubble sort
class ShakerSort extends AlgoTri {
ShakerSort (int t, VueTris v) { super("Shaker Sort", t, v); }
public void sort () {
boolean dep=false;
int curmax=size, curmin=1;
do {
dep=false;
for (int i=curmin; i < curmax; i++)
if (compare(i, i-1)<0) {
exchange(i, i-1);
dep=true;
}
curmax--;
if (!dep) break;
for (int i=curmax-1; i >= curmin; i--)
if (compare(i, i-1)<0) {
exchange(i, i-1);
dep=true;
} curmin++;
} while (dep);
}
};
// select sort is optimal in terms of moves, but catastrophic
// in comparisons: n(n+1)/2 comparisons in all cases...
// Yet, it is the most straightforward algorithm of all.
// Use when when you want to make your users wait...
class SelectSort extends AlgoTri {
SelectSort (int t, VueTris v) { super("Selection Sort", t, v); }
public void sort () {
for (int i = 0; i < size; i++) {
int curmin = i;
for (int j = i+1; j < size; j++) {
if (compare(j, curmin)<0)
curmin=j;
}
if (curmin != i)
exchange(curmin, i);
}
}
};
// insertion sort is the best of the 3 "naive" approaches
// however, it is very bad in terms of moves.
class InsertSort extends AlgoTri {
InsertSort (int t, VueTris v) { super("Insertion Sort", t, v); }
public void sort () {
for (int i = 1; i < size; i++) {
for (int j = i; j > 0; j--) {
if (compare(j, j-1)<0)
exchange(j, j-1);
else break;
}
}
}
};
// dichotomic insertion is a simple optimsation of insertion sort
// it is optimal in terms of comparisons, and does not require
// an additional stack. It does at most sum(i=1 to n)(log2 i)
comparisons.
// however, because of its high moves complexity (n*n), it is still
// less efficient than 'smart' sorts.
// However, it makes an excellent intrdocutino to the notion of
optimizing
// algorithms, and a good intermediate step before introducing
// shell sort
class InsertDichoSort2 extends AlgoTri {
InsertDichoSort2 (int t, VueTris v) { super("Insert-Dicho2", t, v); }
public void sort () {
for (int i = 1; i < size; i++) {
// find by dichotomy before which item to insert the current
int binf=0, bsup=i-1;
int mid=(bsup+binf)/2;
do {
int res=compare(mid,i);
if (res < 0) binf=mid+1;
else if (res > 0) bsup=mid;
else binf=bsup=mid+1;
mid=(bsup+binf)/2;
} while (bsup > binf);
// now insert it before binf
if (mid < i-1) {
int val=item(i);
for (int k = i; k > mid; k--)
exchange(k, k-1);
assign(mid,val);
} else if (compare(i-1,i) > 0) exchange(i,i-1);
}
}
};
class InsertDichoSort extends AlgoTri {
InsertDichoSort (int t, VueTris v) { super("Insert-Dicho", t, v); }
public void sort () {
for (int i = 1; i < size; i++) {
// find by dichotomy before which item to insert the current
if (compare(i-1,i) <= 0) continue;
int binf=0, bsup=i-1;
do {
int mid=(bsup+binf)/2;
int res=compare(mid,i);
if (res < 0) binf=mid+1;
else if (res > 0) bsup=mid;
else binf=bsup=mid+1;
} while (bsup > binf);
// now insert it before binf
int val=item(i);
for (int k = i; k > binf; k--)
exchange(k, k-1);
assign(binf,val);
}
}
};
// the most used sort algorithm. ONce undesrtood it is simple
// to understand. My take is that its efficiency is not so much
// due to redcuing the number of comparisons, but rather that it
// is also very efficient in number of moves.
// worst case is still O(n2), but on quasi sorted strings.
// often seen as a generalization of bubblesort.
// it can also be very demanding in stack use. unfortunatley,
// our visualizer does not show that.
class QuickSort extends AlgoTri {
QuickSort (int t, VueTris v) { super("QuickSort", t, v); }
void sort(int from, int to) {
delay (ext); // emulates recursion's & stack cost
int pivot=item((from+to)/2);
int ma=to; int mi=from;
do {
while(compare_val(pivot, ma)<0) ma--;
while(compare_val(pivot, mi)>0) mi++;
if(mi <= ma) {
if (mi != ma)
exchange(ma, mi);
ma--; mi++;
}
} while (ma>=mi);
if (from < ma) sort(from, ma);
if (to > mi) sort(mi, to);
}
public void sort () {
sort(0,size-1);
}
};
// some local often used improvements over quicksort:
// use the median of 3 values to improve chances of partitioning
// right, and use insertino sort on small lists instead of
// recursion, to minimize stack use and because partitioning
// is not efficient on small quasi ordered lists.
// Note that the 'quasi-ordered' conditions, as we implemented it,
// is one of the cases where these optimizations do not work well.
class QuickerSort extends AlgoTri {
QuickerSort (int t, VueTris v) { super("QuickerSort", t, v); }
void insert_sort (int from, int to) {
delay (ext); // emulates recursion's & stack cost
if (to > from) {
for (int i = from+1; i <= to; i++) {
for (int j = i; j > from; j--) {
if (compare(j, j-1)<0)
exchange(j, j-1);
else break;
}
}
}
}
void sort(int from, int to) {
delay (ext); // emulates recursion's & stack cost
int pivot;
// choose the median of three of the values as a pivot
if (compare(to, from) > 0) {
if (compare((from+to)/2, to) > 0) pivot=item(to);
else {
if (compare((from+to)/2, from) > 0)
pivot=item((from+to)/2);
else pivot=item(from);
}
} else {
if (compare((from+to)/2, from)>0) pivot=item(from);
else {
if (compare((from+to)/2, to) > 0)
pivot=item((from+to)/2);
else pivot=item(to);
}
}
int ma=to; int mi=from;
do {
while(compare_val(pivot, ma)<0) ma--;
while(compare_val(pivot, mi)>0) mi++;
if(mi <= ma) {
if (mi != ma)
exchange(ma, mi);
ma--; mi++;
}
} while (ma>=mi);
// if array is small, do insertion instead of recursion
if (Math.abs(ma - from) > 10) sort(from, ma);
else insert_sort(from, ma);
if (Math.abs(to - mi) > 10) sort(mi, to);
else insert_sort(mi, to);
}
public void sort () {
sort(0,size-1);
}
};
// theoretically a very efficient sort: bounded in nlogn
// a generalization of selection sort.
class HeapSort extends AlgoTri {
HeapSort (int t, VueTris v) { super("HeapSort", t, v); }
boolean isLeaf(int t, int pos) {return (pos >= t/2) && (pos < t) &&
t > 0;}
int leftchild(int pos) {return 2*pos+1;}
int rightchild(int pos) {return 2*pos;}
void siftdown (int t, int pos) {
while (!isLeaf(t, pos)) {
int j = leftchild(pos);
int k = rightchild(pos);
int maxchildindex;
if (compare(k,j) < 0) maxchildindex=j;
else maxchildindex=k;
if (compare(pos, maxchildindex) >= 0) return;
exchange(pos, maxchildindex);
pos = maxchildindex;
}
}
public void sort () {
for (int i = size/2-1; i>=0; i--)
siftdown(size-1, i);
for (int i=size-1; i>1; i--) {
exchange(0,i);
siftdown (i-1, 0);
}
}
};
// the fastest sort before quicksort was invented in 1976
// a generalizatino of insertion sort.
// lots of research has gone in finding the optimum intervals
// of the sequence of separations...
class ShellSort extends AlgoTri {
ShellSort (int t, VueTris v) { super("Shell Sort", t, v); }
void insertionsort (int offset, int n, int incr) {
for (int i = incr; i < n; i+= incr)
for (int j = i; (j >= incr)
&& compare(j+offset, j+offset-incr)< 0; j-=incr)
exchange(j+offset, j+offset-incr);
}
public void sort () {
// here, we use the simplest increment suite.
for (int i = (size/2); i > 1; i /= 2)
for (int j = 0; j < i; j++)
insertionsort(j, size-j, i);
insertionsort(0, size, 1);
}
};
class ShellSort2 extends AlgoTri {
ShellSort2 (int t, VueTris v) { super("Shell Sort2", t, v); }
void insertionsort (int offset, int n, int incr) {
for (int i = incr; i < n; i+= incr)
for (int j = i; (j >= incr)
&& compare(j+offset, j+offset-incr)< 0; j-=incr)
exchange(j+offset, j+offset-incr);
}
public void sort () {
// here, we use a smarter increment suite:
int maxi=1;
while(maxi < size - 1)
maxi=3*maxi+1;
for (int i = maxi/3; i > 1; i /= 3)
for (int j = 0; j < i; j++)
insertionsort(j, size-j, i);
insertionsort(0, size, 1);
}
};
// fastest know in place stable sort.
// no risk of exploding a stack.
// cost: a relatively high number of moves. stack can still
// be expensive too.
// this is a merge sort with a smart in place merge that
// 'rotates' the sub arrays. to see the way it works, view it
// on inverted array
class InPlaceStableSort extends AlgoTri {
InPlaceStableSort (int t, VueTris v) { super("InPlaceStable", t, v);
}
int lower (int from, int to, int val) {
int len = to - from, half;
while (len > 0) {
half = len/2;
int mid= from + half;
if (compare (mid, val) < 0) {
from = mid+1;
len = len - half -1;
} else len = half;
} return from;
}
int upper (int from, int to, int val) {
int len = to - from, half;
while (len > 0) {
half = len/2;
int mid= from + half;
if (compare (val, mid) < 0)
len = half;
else {
from = mid+1;
len = len - half -1;
}
} return from;
}
void insert_sort (int from, int to) {
delay (ext); // emulates recursion's & stack cost
if (to > from+1) {
for (int i = from+1; i < to; i++) {
for (int j = i; j > from; j--) {
if (compare(j, j-1)<0)
exchange(j, j-1);
else break;
}
}
}
}
int gcd (int m, int n) {
while (n!=0) { int t = m % n; m=n; n=t; }
return m;
}
void reverse (int from, int to) {
while (from < to) {
exchange(from++, to--);
}
}
void rotate (int from, int mid, int to) {
/* a less sophisticated but costlier version:
reverse(from, mid-1);
reverse(mid, to-1);
reverse(from, to-1);
*/
if (from==mid || mid==to) return;
int n = gcd(to - from, mid - from);
while (n-- != 0) {
int val = item(from+n);
int shift = mid - from;
int p1 = from+n, p2=from+n+shift;
while (p2 != from + n) {
assign(p1, item(p2));
p1=p2;
if ( to - p2 > shift) p2 += shift;
else p2=from + (shift - (to - p2));
} assign(p1, val);
}
}
void merge(int from, int pivot, int to, int len1, int len2) {
delay(ext); // emulates stack and recursion's costs
if (len1 == 0 || len2==0) return;
if (len1+len2 == 2) {
if (compare(pivot, from) < 0)
exchange(pivot, from);
return;
}
int first_cut, second_cut;
int len11, len22;
if (len1 > len2) {
len11=len1/2;
first_cut = from + len11;
second_cut = lower(pivot, to, first_cut);
len22 = second_cut - pivot;
} else {
len22 = len2/2;
second_cut = pivot + len22;
first_cut = upper(from, pivot, second_cut);
len11=first_cut - from;
}
rotate(first_cut, pivot, second_cut);
int new_mid=first_cut+len22;
merge(from, first_cut, new_mid, len11, len22);
merge(new_mid, second_cut, to, len1 - len11, len2 - len22);
}
void sort(int from, int to) {
delay (ext); // emulates recursion's & stack cost
if (to - from < 12) {
insert_sort (from, to);
return;
}
int middle = (from + to)/2;
sort (from, middle);
sort (middle, to);
merge(from, middle, to, middle-from, to - middle);
}
public void sort () {
sort(0, size);
}
};
abstract class AlgoTri extends Thread {
// the important members
int size;
int tableau[];
String nom;
float cmpt, ext;
// to make statistics
int nEchanges;
int nCompare;
int lastcomp1, lastcomp2;
int lastchange1, lastchange2;
VueTris visu;
// to optimize repaint:
boolean damaged=false;
Point damages[];
int damage_cnt=0;
// to allow restarting a sort
boolean started=false;
AlgoTri(String n, int t, VueTris v) {
super(n);
nom=n;
cmpt=50; ext=10;
visu=v;
size=t;
tableau=new int [t];
damages=new Point [200];
for (int i=0;i<200;i++)
damages[i]=new Point(0,0);
reinit("Sorted", (float) .5, (float) .1);
}
// members to be used exclusively in subclasses to handle the sort
public void exchange (int i, int j) {
damage(i, tableau[i]);
damage(j, tableau[j]);
int tmp=tableau[i];
tableau[i]=tableau[j];
tableau[j]=tmp;
damage(lastchange1, tableau[lastchange1]);
damage(lastchange2, tableau[lastchange2]);
lastchange1=i;lastchange2=j;
damage(i, tableau[i]);
damage(j, tableau[j]);
nEchanges++;
delay(ext);
}
public int compare (int i, int j) {
nCompare++;
damage(lastcomp1, tableau[lastcomp1]);
damage(lastcomp2, tableau[lastcomp2]);
lastcomp1=i;lastcomp2=j;
damage(i, tableau[i]);
damage(j, tableau[j]);
delay(cmpt);
return tableau[i] - tableau[j];
}
public int compare_val (int val, int i) {
nCompare++;
damage(lastcomp1, tableau[lastcomp1]);
lastcomp1=i;
damage(i, tableau[i]);
delay(cmpt);
return val - tableau[i];
}
public void assign (int ndx, int val) {
damage(lastchange1, tableau[lastchange1]);
damage(lastchange2, tableau[lastchange2]);
lastchange1=lastchange2=ndx;
damage(ndx, val);
damage(ndx, tableau[ndx]);
tableau[ndx]=val;
nEchanges++;
delay(ext);
}
public int item (int i) {
damage(lastcomp2, tableau[lastcomp2]);
lastcomp2=i;
return tableau[i];
}
public void delay(float f) {
if (f==0) return;
try {
sleep((long)f);
} catch (Exception e) { if (e != null) e.printStackTrace();}
}
// utilities used internally
boolean dlocked=false;
// making this synchronized really broke the scheduler
//
synchronized void get_damage_lock() {
while (dlocked) { try { wait(); } catch (Exception e) {}}
dlocked = true;
} synchronized void release_damage_lock() { dlocked=false; notifyAll();
}
public void damage (int i, int ndx) {
get_damage_lock();
damaged=true;
damages[damage_cnt].x=i;
damages[damage_cnt].y=ndx;
if (damage_cnt < 199) damage_cnt++;
// damages.addElement(p);
release_damage_lock();
visu.repairs.wakeup();
}
public void common_paint(int x, int y, Graphics g) {
g.setColor(visu.mvcolor);
g.fillRect(x+1+lastchange1*2, y+1+(size-tableau[lastchange1])*2, 2,
2);
g.fillRect(x+1+lastchange2*2, y+1+(size-tableau[lastchange2])*2, 2,
2);
g.setColor(visu.cpcolor);
g.fillRect(x+1+lastcomp1*2, y+1+(size-tableau[lastcomp1])*2, 2,2);
g.fillRect(x+1+lastcomp2*2, y+1+(size-tableau[lastcomp2])*2, 2,2);
g.setColor(visu.fgcolor);
g.setFont(visu.font);
float val=(float) ((((float)nEchanges)*ext)/100.0 +
(((float)nCompare)*cmpt)/100.0);
g.drawString(Integer.toString(nCompare), x+100, y+size*2 + 18);
g.drawString(Integer.toString(nEchanges), x+135, y+size*2 + 18);
g.drawString(Float.toString(val), x+170, y+size*2 + 18);
damaged=false;
damage_cnt=0;
}
public void repair (int x, int y, Graphics g) {
if (!damaged) return;
get_damage_lock();
// for each item in damages: clear it even if it is useless
// this should be optimized, because it makes some sorts look faster
than others...
g.setColor(visu.cellcolor);
for (int i=0; i<damage_cnt; i++) {
Point p = damages[i];
g.clearRect(x+1+p.x*2, y+1+(size-p.y)*2, 2, 2);
}
// for each index in the damage array: paint the correct item
for (int i=0; i<damage_cnt; i++) {
Point p = damages[i];
if (p.x != lastchange1 && p.x!= lastchange2 && p.x!= lastcomp1 &&
p.x != lastcomp2)
g.fillRect(x+1+p.x*2, y+1+(size-tableau[p.x])*2, 2, 2);
}
g.clearRect(x+100, y+size*2+6, 115, 20);
common_paint(x, y, g);
release_damage_lock();
}
public void dessine (int x, int y, Graphics g) {
get_damage_lock();
g.clearRect(x-2, y-2, size*2+4, y+size*2+20);
g.setColor(visu.cellcolor);
for (int i=0; i < size; i++) {
if (i != lastchange1 && i!= lastchange2 && i!= lastcomp1 && i !=
lastcomp2)
g.fillRect(x+1+i*2, y+ 1+(size-tableau[i])*2, 2, 2);
}
g.setColor(visu.fgcolor);
g.setFont(visu.font);
g.drawString(nom, x+10, y+size*2 + 18);
g.drawRect(x, y, size*2+2, size*2+4);
common_paint(x, y, g);
release_damage_lock();
}
abstract void sort();
public synchronized void go() {
started=true;
if (!isAlive()) start();
else notifyAll();
}
public void run() {
while (true) {
if (started) {
nEchanges=nCompare=0;
delay(100);
sort();
started=false;
delay(100);
} idle();
}
}
synchronized void idle() {
try { wait(); } catch(Exception e) {}
}
boolean reinit(String s, float c, float e) {
boolean res=false;
cmpt=c*100; ext=e*100;
if (started) return true;
if (s.equals("riées")) {
for (int i=0; i< size; i++)
tableau[i]=i;
res=true;
} else if (s.equals("Inversées")) {
for (int i=0; i< size; i++)
tableau[i]=size - i - 1;
res=true;
} else if (s.equals("Arbitraire")) {
for (int i=0; i< size; i++)
tableau[i] = (int) (Math.random()*(double)size);
res=true;
} else if (s.equals("Presque triées")) {
for (int i=0; i< size; i++)
tableau[i]= Math.abs(i + (int) (Math.random()*(double) 10) - 5) %
size;
res=true;
} else if (s.equals("Presque inversées")) {
for (int i=0; i< size; i++)
tableau[i]= Math.abs(size - i + (int) (Math.random()*(double) 10)
- 5) % size;
res=true;
} else if (s.equals("Triangle")) {
for (int i=0; i< size/2; i++)
tableau[i]= i*2;
for (int i=size/2; i< size; i++)
tableau[i]= (size - i)*2;
res=true;
} else if (s.equals("Triangle inversé")) {
for (int i=0; i< size/2; i++)
tableau[i]= (size - i*2);
for (int i=size/2; i < size; i++)
tableau[i]= (i*2-size);
res=true;
} else if (s.equals("Cloche")) {
for (int i=0; i< size; i++)
tableau[i]= (int)
(Math.sin(((double)i)/((double)size)*3.14)*(double)size);
res=true;
}
if (res) visu.repaint();
return res;
}
};
class VueTris extends Canvas {
VisuTri visu;
RepairThread repairs;
Thread drawthread;
Font font;
Color fgcolor=new Color(255,255,255);
Color cellcolor=new Color(0,255,0);
Color mvcolor = new Color(255,0,255);
Color cpcolor= new Color(255,0,0);
boolean drawing=false;
VueTris (VisuTri v) {
super();
visu=v;
font=new Font("Helvetica", 0, 10);
repairs=new RepairThread(this);
repairs.start();
}
synchronized void drawing_lock() {
while(drawing) { try { wait(); } catch(Exception e) {}}
drawing=true;
}
synchronized void release_lock() { drawing=false; notifyAll(); }
public void paint (Graphics g) {
drawing_lock();
int k=0;
boolean simple_repair=false;
if (g == null) {
g=getGraphics(); simple_repair=true;
}
if (g==null) return;
for (int j=0; k<visu.algos.size() && j < 400; j+=230)
for (int i = 0; k < visu.algos.size() && i < 600; i+= 210) {
if (simple_repair)
((AlgoTri) visu.algos.elementAt(k++)).repair(i+5, j+10, g);
else
((AlgoTri) visu.algos.elementAt(k++)).dessine (i+5, j+10, g);
} release_lock();
}
}
class RepairThread extends Thread {
RepairThread(VueTris v) { super("RepairThread"); visu=v; waken=false;
}
public void run() { while(true) loop(); }
synchronized void loop() {
try { wait(100); } catch (Exception e) {}
while (waken) {
waken=false;
visu.paint(null);
}
}
public void wakeup() { waken=true; }
boolean waken;
VueTris visu;
};
/**
* Put the class description here.
* @author Thomas Baudel
* @version VERSION 1 extended
**/
public class VisuTri extends Applet {
public void init() {
super.init();
algos=new Vector(0);
setLayout(null);
Color bg=new Color(0x333333);
Color fg=new Color(0xffffff);
Font font=new Font("Helvetica", 0, 12);
setBackground(bg);
resize(640, 512);
add(canvas = new VueTris(this));
canvas.setBackground(new Color(0,0,0));
canvas.move(0, 32);
canvas.resize(640, 480);
canvas.show();
add(TypeTri = new java.awt.Choice());
TypeTri.addItem("Selection");
TypeTri.addItem("BubbleSort");
TypeTri.addItem("ShakerSort");
TypeTri.addItem("Insertion");
TypeTri.addItem("Insert/Dicho");
TypeTri.addItem("Insert/Dicho2");
TypeTri.addItem("HeapSort");
TypeTri.addItem("QuickSort");
TypeTri.addItem("QuickerSort");
TypeTri.addItem("ShellSort");
TypeTri.addItem("ShellSort2");
TypeTri.addItem("In Place Stable");
TypeTri.addItem("________________");
TypeTri.addItem("Clear All");
TypeTri.setFont(font);
TypeTri.move(5, 2);
TypeTri.resize(120, 26);
TypeTri.setBackground(bg);
TypeTri.setForeground(fg);
TypeTri.show();
add(Action = new java.awt.Choice());
Action.addItem("Arbitraire");
Action.addItem("Triées");
Action.addItem("Inversées");
Action.addItem("Presque triées");
Action.addItem("Presque inversées");
Action.addItem("Triangle");
Action.addItem("Triangle inversé");
Action.addItem("Cloche");
Action.addItem("Custom");
Action.addItem("_______________");
Action.addItem("Suspend");
Action.addItem("Resume");
Action.setFont(font);
Action.move(127, 2);
Action.resize(130, 26);
Action.setBackground(bg);
Action.setForeground(fg);
Action.show();
add(label = new java.awt.Label());
label.setText("Compare");
label.setBackground(bg);
label.setForeground(fg);
label.setFont(font);
label.setAlignment(2);
label.move(259, 2);
label.resize(80, 26);
label.show();
add(textfield = new java.awt.TextField());
textfield.setText(".5");
textfield.setBackground(new Color(0x000000));
textfield.setForeground(fg);
textfield.move(341, 1);
textfield.resize(40, 28);
textfield.show();
add(label1 = new java.awt.Label());
label1.setText("Exchange");
label1.setBackground(bg);
label1.setForeground(fg);
label1.setFont(font);
label1.setAlignment(2);
label1.move(383, 2);
label1.resize(80, 26);
label1.show();
add(textfield1 = new java.awt.TextField());
textfield1.setText(".1");
textfield1.setBackground(new Color(0x000000));
textfield1.setForeground(fg);
textfield1.move(465, 1);
textfield1.resize(40, 28);
textfield1.show();
init_for_netscape_bug();
}
public boolean action (Event evt, Object arg) {
if (AjouteTri(new String(arg.toString()))) return true;
else Simule(arg.toString());
return false;
}
public boolean AjouteTri (String arg) {
boolean res=false;
if (arg.equals("Clear All")) {
for (int i =0; i < algos.size(); i++) {
AlgoTri t = (AlgoTri) algos.elementAt(i);
t.stop();
}
algos.removeAllElements();
algos.setSize(0);
Graphics g = canvas.getGraphics();
Rectangle bounds = canvas.bounds();
if (g!=null) g.clearRect(0, 0, bounds.width, bounds.height);
res=true;
} else if (arg.equals("BubbleSort")) {
algos.addElement(new BubbleSort(100, canvas));
res=true;
} else if (arg.equals("Selection")) {
algos.addElement(new SelectSort(100, canvas));
res=true;
} else if (arg.equals("Insertion")) {
algos.addElement(new InsertSort(100, canvas));
res=true;
} else if (arg.equals("QuickSort")) {
algos.addElement(new QuickSort(100, canvas));
res=true;
}else if (arg.equals("Insert/Dicho" )) {
algos.addElement(new InsertDichoSort(100, canvas));
res=true;
}else if (arg.equals("Insert/Dicho2" )) {
algos.addElement(new InsertDichoSort2(100, canvas));
res=true;
}else if (arg.equals("ShakerSort" )) {
algos.addElement(new ShakerSort(100, canvas));
res=true;
}else if (arg.equals("QuickerSort" )) {
algos.addElement(new QuickerSort(100, canvas));
res=true;
}else if (arg.equals("HeapSort" )) {
algos.addElement(new HeapSort(100, canvas));
res=true;
}else if (arg.equals("ShellSort")) {
algos.addElement(new ShellSort(100, canvas));
res=true;
}else if (arg.equals("ShellSort2")) {
algos.addElement(new ShellSort2(100, canvas));
res=true;
}else if (arg.equals("In Place Stable")) {
algos.addElement(new InPlaceStableSort(100, canvas));
res=true;
}
if (res) canvas.repaint();
return res;
}
void init_for_netscape_bug () {
new BubbleSort(100, canvas);
new SelectSort(100, canvas);
new InsertSort(100, canvas);
new QuickSort(100, canvas);
new InsertDichoSort(100, canvas);
new InsertDichoSort2(100, canvas);
new ShakerSort(100, canvas);
new QuickerSort(100, canvas);
new HeapSort(100, canvas);
new ShellSort(100, canvas);
new ShellSort2(100, canvas);
new InPlaceStableSort(100, canvas);
}
synchronized public void Simule (String arg) {
if (arg.equals("Suspend")) {
for (int i =0; i < algos.size(); i++) {
AlgoTri t = (AlgoTri) algos.elementAt(i);
if (t.isAlive()) t.suspend();
}
} if (arg.equals("Resume")) {
for (int i =0; i < algos.size(); i++) {
AlgoTri t = (AlgoTri) algos.elementAt(i);
if (t.isAlive()) t.resume();
}
} else {
boolean reinitialized=true;
for (int i =0; i < algos.size(); i++) {
AlgoTri t = (AlgoTri) algos.elementAt(i);
reinitialized &= t.reinit((String) arg,
new Float(textfield.getText()).floatValue(),
new Float(textfield1.getText()).floatValue());
}
if (reinitialized) {
for (int i =0; i < algos.size(); i++) {
AlgoTri t = (AlgoTri) algos.elementAt(i);
t.go();
}
Graphics g = canvas.getGraphics();
Rectangle bounds = canvas.bounds();
if (g!=null) g.clearRect(0, 0, bounds.width, bounds.height);
canvas.repaint();
}
}
}
VueTris canvas;
java.awt.Choice TypeTri;
java.awt.TextField textfield;
java.awt.Label label;
java.awt.Label label1;
java.awt.TextField textfield1;
java.awt.Choice Action;
Vector algos;
}