java wiele grafik [zamknięte]
Dobrze, więc przez jakiś czas pracowałem nad tym kodem, który pokazuje, jak działają algorytmy sortowania. W tej chwili działam tam, gdzie sortuje wiele wykresów z tym samym sortowaniem, ale potrzebuję każdego wykresu do innego sortowania w tym samym czasie. Badam i próbuję rozwiązać ten problem od wielu dni, a teraz mam tylko wizję tunelową. Opublikuję mój kod na wypadek, gdyby moje wyjaśnienie było mylące. Wydaje mi się, że może to przynieść korzyści wielu osobom pracującym z grafiką java i każda pomoc byłaby doceniana.
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Scanner;
public class Sort extends Applet {
/** Constructor. Only for starting the sorting animation as applet. */
public Sort() {}
/** For starting the sorting animation as application. */
public static void main(String[] argv) {
Frame _aFrame = new Frame("Sort Animations");
_aFrame.setBackground(Color.white);
_aFrame.setPreferredSize(new Dimension(2700,1000));
Scanner in = new Scanner(System.in);
int sizeOfArray;
System.out.println("How many numbers do you want to sort?");
sizeOfArray = in.nextInt();
_aFrame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) { System.exit(0); }
}
);
_aFrame.setLayout(new BorderLayout());
_aFrame.add(new SortPanel(sizeOfArray));
_aFrame.pack();
_aFrame.setVisible(true);
}
}
class SortPanel extends Panel implements Runnable {
/** button triggering the sort animation */
private Button aSortButton_ = new Button("sort");
/** choice item for selecting the sort algorithm */
private Choice aChoice_ = new Choice();
/** component for handling the animation */
private ArrayCanvas anArrayCanvas_;
/////////////////////////////////////////////////////////////////////////////
/**
* Constructor.
*
* @param length no of elements of the array
* @param aBarColor the color the elements representing bars will be drawn in
*
* @exception IllegalArgumentException if the array <code>length</code> is
* to big to display (ie <code>length</code> is bigger than
* <code>BAR_WIDTH</code> or <code>BAR_HEIGHT</code>).
*/
public SortPanel(int arraySize) {
setLayout(new BorderLayout());
aSortButton_.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Thread(SortPanel.this).start();
}
}
);
anArrayCanvas_ = new ArrayCanvas(arraySize);
for (int i=0; i<ArrayCanvas.SORT_NAMES.length; ++i)
aChoice_.add(ArrayCanvas.SORT_NAMES[i]);
// add buttons at top:
Panel _aTopPanel = new Panel();
_aTopPanel.add(aSortButton_);
add(_aTopPanel, BorderLayout.NORTH);
// add choice and ArrayCanvas below:
Panel _aPanel = new Panel();
_aPanel.setLayout(new BorderLayout());
Panel _aChoicePanel = new Panel();
_aChoicePanel.add(aChoice_);
_aPanel.add(_aChoicePanel, BorderLayout.NORTH);
_aPanel.add(anArrayCanvas_, BorderLayout.CENTER);
add(_aPanel, BorderLayout.CENTER);
Panel _aBottomPanel = new Panel();
add(_aBottomPanel, BorderLayout.SOUTH);
}
/////////////////////////////////////////////////////////////////////////////
/** Runs the sorting animation. */
public void run() {
aSortButton_.setEnabled(false);
double time = System.currentTimeMillis();
anArrayCanvas_.sort(aChoice_.getSelectedItem());
aSortButton_.setEnabled(true);
}
}
class ArrayCanvas extends Canvas {
/** Labels of available sorting algorithms. */
public final static String[] SORT_NAMES = { "bubble sort", "insertion sort", "shell sort", "heap sort", "merge sort", "quick sort",};
/** offset between bars and border in x-directions (left and right) */
public final static int OFFSET_X = 5;
/** offset between bars and border in y-directions (top and bottom) */
public final static int OFFSET_Y = 5;
/** horizontal size of all bars together */
public final static int BAR_WIDTH = 350;
/** (max) vertical horizontal size of bars together */
public final static int BAR_HEIGHT = 250;
/** milliseconds to sleep after a swap in the sorting animation */
public final static int SLEEP_AFTER_SWAP = 20;
/** used for random permutation of the array elements */
private static Random aRandom_ = new Random(System.currentTimeMillis());
/** the array to display */
private int[] anArrayOfInt_;
/** offscreen buffer */
private Image image_;
/** graphics of the offscreen buffer */
private Graphics offscreenGraphics_;
/////////////////////////////////////////////////////////////////////////////
/**
* Constructor.
*
* @param length no of elements of the array
*
* @exception IllegalArgumentException if the array <code>length</code> is
* to big to display (ie <code>length</code> is bigger than
* <code>BAR_WIDTH</code> or <code>BAR_HEIGHT</code>).
*/
public ArrayCanvas(int length) {
if (length > BAR_WIDTH || length > BAR_HEIGHT)
throw new IllegalArgumentException("array to big: "+length);
anArrayOfInt_ = new int[length];
for (int i=0; i<length; ++i)
anArrayOfInt_[i] = i+1;
permute();
addMouseListener(
new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
repaint();
}
}
);
}
/////////////////////////////////////////////////////////////////////////////
// overloaded for double buffering
public void update(Graphics aGraphics) {
paint(aGraphics);
}
/** displays the array */
public void paint(Graphics aGraphics) {
int _deltaX = 0;
int w = BAR_WIDTH / anArrayOfInt_.length;
if (w > 1) {
--w;
++_deltaX;
}
int _heightFactor = BAR_HEIGHT / anArrayOfInt_.length;
if (offscreenGraphics_ == null) {
image_ = createImage(getSize().width, getSize().height);
offscreenGraphics_ = image_.getGraphics();
}
offscreenGraphics_.setColor(getBackground());
offscreenGraphics_.fillRect(0, 0, getSize().width-1, getSize().height-1);
offscreenGraphics_.setColor(Color.black);
//offscreenGraphics_.drawRect(0, 0, getSize().width-1, getSize().height-1);
offscreenGraphics_.translate(OFFSET_X, OFFSET_Y);
for (int i=0; i<anArrayOfInt_.length; ++i) {
int h = _heightFactor*anArrayOfInt_[i];
offscreenGraphics_.setColor(Color.blue);
offscreenGraphics_.fillRect((w+_deltaX)*i, BAR_HEIGHT-h, w, h);
if(anArrayOfInt_[i]==(i+1)){
offscreenGraphics_.setColor(Color.red);
offscreenGraphics_.fillRect((w+_deltaX)*i, BAR_HEIGHT-h, w, _heightFactor);
}
}
offscreenGraphics_.translate(-OFFSET_X, -OFFSET_Y);
aGraphics.drawImage(image_, 0, 0, this);
aGraphics.drawImage(image_, 475, 0, this);
aGraphics.drawImage(image_, 950, 0, this);
aGraphics.drawImage(image_, 0, 350, this);
aGraphics.drawImage(image_, 475, 350, this);
aGraphics.drawImage(image_, 950, 350, this);
}
public Dimension getMinimumSize() {
return new Dimension(BAR_WIDTH+2*OFFSET_X, BAR_HEIGHT+2*OFFSET_Y);
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
///////////////////////////////////////////////////
/** random permutation of array entries */
public void permute() {
for (int i=anArrayOfInt_.length-1; i>0; --i) {
int j = Math.abs(aRandom_.nextInt()) % (i+1);
swap(anArrayOfInt_,i,j);
}
}
/** animated sort */
public void sort(String aSortNameString) {
mySort(aSortNameString);
}
///////////////////////////////////////////////////
private void mySort(String aSortNameString) {
if (aSortNameString.equals("bubble sort")) {
bubbleSort(anArrayOfInt_);
}
if (aSortNameString.equals("insertion sort")) {
insertionSort(anArrayOfInt_);
}
if (aSortNameString.equals("selection sort")) {
selectionSort(anArrayOfInt_);
}
if (aSortNameString.equals("shell sort")) {
shellSort(anArrayOfInt_);
}
if (aSortNameString.equals("heap sort")) {
heapSort(anArrayOfInt_);
}
if (aSortNameString.equals("merge sort")) {
mergeSort(anArrayOfInt_, 0, anArrayOfInt_.length-1);
}
if (aSortNameString.equals("quick sort")) {
qSort(anArrayOfInt_, 0, anArrayOfInt_.length-1);
}
}
/**
* swaps the two array elements, redisplays the array in its canvas,
* and waits a moment.
*/
private void swap(int[] anArrayOfInt, int i, int j) {
int x = anArrayOfInt[i];
anArrayOfInt[i] = anArrayOfInt[j];
anArrayOfInt[j] = x;
repaint();
try { Thread.sleep(SLEEP_AFTER_SWAP); } catch (InterruptedException e) {}
}
/////////////////////////////////////////////////////////////////////////////
// SORTING ALGORITHMS //
/////////////////////////////////////////////////////////////////////////////
/** bubble sort */
private void bubbleSort(int[] anArrayOfInt) {
for (int i=0; i<anArrayOfInt.length; ++i)
for (int j=1; j<anArrayOfInt.length-i; ++j)
if (anArrayOfInt[j-1]>anArrayOfInt[j]) {
swap(anArrayOfInt, j-1, j);
}
}
/** insertion sort */
private void insertionSort(int[] anArrayOfInt) {
for (int i=0; i<anArrayOfInt.length; ++i)
for (int j=i-1; j>=0 && anArrayOfInt[j]>anArrayOfInt[j+1]; --j)
swap(anArrayOfInt, j, j+1);
}
/** selection sort */
private void selectionSort(int[] anArrayOfInt) {
for (int i=0; i<anArrayOfInt.length-1; ++i) {
for (int j=i+1; j<anArrayOfInt.length; ++j)
if (anArrayOfInt[j] < anArrayOfInt[i])
swap(anArrayOfInt, i, j);
}
}
/** shell sort */
private void shellSort(int[] anArrayOfInt) {
// TODO: calculate needed STEPS-elements instead of using an array
// (STEPS[i+1] = 3*STEPS[i]+1)
for (int i=0; i<STEPS.length; ++i) {
int _delta = STEPS[i];
if (_delta >= anArrayOfInt.length)
continue;
for (int j=_delta; j<anArrayOfInt.length; ++j)
for (int k=j; k-_delta>=0 && anArrayOfInt[k]<anArrayOfInt[k- _delta];
k-=_delta)
swap(anArrayOfInt, k, k-_delta);
}
}
/** used by shell sort */
private final static int[] STEPS = { 1093, 364, 121, 40, 13, 4, 1 };
/** heap sort */
private void heapSort(int[] anArrayOfInt) {
int r = anArrayOfInt.length-1;
for (int l = anArrayOfInt.length/2 ; l>=0; --l)
sift(anArrayOfInt, l, r);
while (r > 0) {
swap(anArrayOfInt, 0, r);
sift(anArrayOfInt, 0, --r);
}
}
/** auxiliary function for heap sort. */
private void sift(int[] anArrayOfInt, int l, int r) {
if (r==l)
return;
int i = l, j = 2*l;
int x = anArrayOfInt[i];
if (j<r && anArrayOfInt[j]<anArrayOfInt[j+1])
++j;
while (j<=r && x<=anArrayOfInt[j]) {
swap(anArrayOfInt, i, j);
i = j; j = 2*j;
if (j<r && anArrayOfInt[j]<anArrayOfInt[j+1])
++j;
}
}
/** quick sort (pivot=(l+r)/2)*/
private void qSort(int[] anArrayOfInt, int l, int r) {
if (l >= r)
return;
swap(anArrayOfInt, l, (l+r)/2); // TODO: more clever pivot
int _last = l;
for (int i=l+1; i<=r; ++i)
if (anArrayOfInt[i] < anArrayOfInt[l])
swap(anArrayOfInt, ++_last, i);
swap(anArrayOfInt, l, _last);
qSort(anArrayOfInt, l, _last-1);
qSort(anArrayOfInt, _last+1, r);
}
/** merge sort */
private void mergeSort(int[] anArrayOfInt, int l, int r) {
int[][] B = new int[2][r+1];
mergeSort16(anArrayOfInt, B, l, r);
}
private void mergeSort16(int[] anArrayOfInt, int[][] B, int l, int r) {
if (l >= r)
return;
int _last = (l+r)/2;
mergeSort16(anArrayOfInt, B, l, _last);
mergeSort16(anArrayOfInt, B, _last+1, r);
merge6(anArrayOfInt, B, l, _last, r);
}
/** auxiliary function for merge sort */
protected void merge6(int[] anArrayOfInt, int[][] B, int l, int q, int r) {
for (int i=l;i<=q;i++) {
B[0][i] = i;
B[1][i] = i;
}
for (int i=r;i>q;i--) {
B[0][i] = r+q+1-i;
B[1][i] = r+q+1-i;
}
int i = l;
int j = r;
for (int k=l; k<r;k++) {
int s = B[0][i];
int t = B[0][j];
if (anArrayOfInt[s]<=anArrayOfInt[t]) {
i++;
} else {
s = t;
j--;
}
swap(anArrayOfInt, s, k);
t = B[1][k];
B[0][t] = s;
B[1][s] = t;
}
}
}