私のアルゴリズム クラスの課題は、配列に対してマージソートを実行し、何が起こっているかをアニメーションとして表示することです。コードは (理論的には) 動作していますが、(配列をアニメーション化するために) repaint() を何度もすばやく呼び出すと、それらは無視されます。アニメーションは表示されず、最終的な配列のみが表示されます。コンソールでは、すべての「 * 」の後に「-」が 1 つあるはずですが、そうではありません。「 * 」はたくさんありますが (そうあるべきです)、「-」は 1 つしかありません。' * ' は repaint メソッドが呼び出されるタイミングを示し、'-' は実際に呼び出されるタイミングを示します。
package a2;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class GraphicalSort extends JFrame implements ActionListener {
int[] data = new int[200];
int[] helper = new int[200];
JPanel panel = new JPanel(); //Panel to hold graphical display of array
JPanel buttonsPanel = new JPanel();
JButton mButton = new JButton("Mergesort");
JButton sButton = new JButton("Scramble");
//Constants to scale the width and height
int barWidth = 8;
int barHeight = 1;
public GraphicalSort() {
setLayout(new BorderLayout());
mButton.addActionListener(this);
sButton.addActionListener(this);
buttonsPanel.add(sButton);
buttonsPanel.add(mButton);
for (int i = 0; i < data.length; i++) {
data[i] = (int) (500 * Math.random() + 1);
helper[i] = data[i];
}
setSize(barWidth * data.length, barHeight * 500 + buttonsPanel.getHeight());
panel = new ArrayPanel();
add(buttonsPanel, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
repaint();
validate();
}
public static void main(String[] args) {
GraphicalSort gs = new GraphicalSort();
gs.setTitle("Graphical Sort");
gs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gs.setLocationRelativeTo(null);
gs.setResizable(false);
gs.setVisible(true);
}
@SuppressWarnings("serial")
class ArrayPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
System.out.println("-"); //when repaint is actually called
int xPos = 0;
for (int i = 0; i < data.length; i++) {
g.fillRect(xPos, (barHeight * 500) - (barHeight * data[i]), barWidth, barHeight * data[i]);
xPos += barWidth;
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == mButton) {
mergesort(0, data.length - 1);
} else if (e.getSource() == sButton) {
Random r = new Random();
for (int i = 0; i < data.length; i++) {
int index = r.nextInt(data.length);
int temp = data[i];
data[i] = data[index];
data[index] = temp;
panel.repaint();
}
}
}
private void mergesort(int low, int high) {
// Check if low is smaller then high, if not then the array is sorted
if (low < high) {
// Get the index of the element which is in the middle
int middle = (low + high) / 2;
// Sort the left side of the array
mergesort(low, middle);
// Sort the right side of the array
mergesort(middle + 1, high);
// Combine them both
merge(low, middle, high);
System.out.println("*"); //When the repaint should be called
panel.repaint();
}
}
private void merge(int low, int middle, int high) {
// Copy both parts into the helper array
for (int i = low; i <= high; i++) {
helper[i] = data[i];
}
int i = low;
int j = middle + 1;
int k = low;
// Copy the smallest values from either the left or the right side back
// to the original array
while (i <= middle && j <= high) {
if (helper[i] <= helper[j]) {
data[k] = helper[i];
i++;
} else {
data[k] = helper[j];
j++;
}
k++;
}
// Copy the rest of the left side of the array into the target array
while (i <= middle) {
data[k] = helper[i];
k++;
i++;
}
}
}