Java | ソートアルゴリズムの図解(バブルソート/選択ソート/高速ソートのイメージ)

Java Java
スポンサーリンク

では 7種類のソート(バブル・選択・挿入・マージ・クイック・ヒープ・シェル)を選択してアニメーション表示できるフル GUI版 を作ります。

特徴:

  • ドロップダウンでソート種類を選択
  • 「開始」ボタンでアニメーション
  • 配列は棒グラフで表示、スワップやマージなどの操作を視覚化
  • 初心者でも各ソートの動きを直感的に理解可能

7種類ソートアニメーション GUI 完全版

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

public class FullSortVisualizerGUI extends JPanel {

    private int[] array;
    private int[] originalArray;
    private int delay = 300; // ms
    private String currentSort = "バブルソート";

    public FullSortVisualizerGUI(int[] array) {
        this.originalArray = Arrays.copyOf(array, array.length);
        this.array = Arrays.copyOf(array, array.length);
        setPreferredSize(new Dimension(600, 400));
    }

    // 棒グラフ描画
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int w = getWidth() / array.length;
        for (int i = 0; i < array.length; i++) {
            g.setColor(Color.BLUE);
            g.fillRect(i * w, getHeight() - array[i] * 30, w - 2, array[i] * 30);
            g.setColor(Color.BLACK);
            g.drawRect(i * w, getHeight() - array[i] * 30, w - 2, array[i] * 30);
        }
    }

    // 配列更新して再描画
    private void updateArray(int[] arr) {
        System.arraycopy(arr, 0, array, 0, arr.length);
        repaint();
        try { Thread.sleep(delay); } catch (InterruptedException e) {}
    }

    // --------------------------
    // バブルソート
    // --------------------------
    public void bubbleSort() {
        int n = array.length;
        for (int i = 0; i < n - 1; i++) {
            boolean swapped = false;
            for (int j = 0; j < n - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    int tmp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = tmp;
                    swapped = true;
                    updateArray(array);
                }
            }
            if (!swapped) break;
        }
    }

    // --------------------------
    // 選択ソート
    // --------------------------
    public void selectionSort() {
        int n = array.length;
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (array[j] < array[minIndex]) minIndex = j;
            }
            if (i != minIndex) {
                int tmp = array[i]; array[i] = array[minIndex]; array[minIndex] = tmp;
                updateArray(array);
            }
        }
    }

    // --------------------------
    // 挿入ソート
    // --------------------------
    public void insertionSort() {
        int n = array.length;
        for (int i = 1; i < n; i++) {
            int key = array[i];
            int j = i - 1;
            while (j >= 0 && array[j] > key) {
                array[j + 1] = array[j];
                j--;
                updateArray(array);
            }
            array[j + 1] = key;
            updateArray(array);
        }
    }

    // --------------------------
    // マージソート
    // --------------------------
    public void mergeSort() {
        mergeSort(array, 0, array.length - 1);
    }

    private void mergeSort(int[] arr, int left, int right) {
        if (left >= right) return;
        int mid = (left + right) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
        updateArray(arr);
    }

    private void merge(int[] arr, int left, int mid, int right) {
        int[] tmp = new int[right - left + 1];
        int i = left, j = mid + 1, k = 0;
        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) tmp[k++] = arr[i++];
            else tmp[k++] = arr[j++];
        }
        while (i <= mid) tmp[k++] = arr[i++];
        while (j <= right) tmp[k++] = arr[j++];
        for (int t = 0; t < tmp.length; t++) arr[left + t] = tmp[t];
    }

    // --------------------------
    // クイックソート
    // --------------------------
    public void quickSort() {
        quickSort(array, 0, array.length - 1);
    }

    private void quickSort(int[] arr, int left, int right) {
        if (left >= right) return;
        int pivot = arr[(left + right) / 2];
        int index = partition(arr, left, right, pivot);
        updateArray(arr);
        quickSort(arr, left, index - 1);
        quickSort(arr, index, right);
    }

    private int partition(int[] arr, int left, int right, int pivot) {
        while (left <= right) {
            while (arr[left] < pivot) left++;
            while (arr[right] > pivot) right--;
            if (left <= right) {
                int tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp;
                left++; right--;
            }
        }
        return left;
    }

    // --------------------------
    // ヒープソート
    // --------------------------
    public void heapSort() {
        int n = array.length;
        for (int i = n / 2 - 1; i >= 0; i--) heapify(array, n, i);
        updateArray(array);

        for (int i = n - 1; i >= 0; i--) {
            int tmp = array[0]; array[0] = array[i]; array[i] = tmp;
            heapify(array, i, 0);
            updateArray(array);
        }
    }

    private void heapify(int[] arr, int size, int i) {
        int largest = i;
        int left = 2 * i + 1, right = 2 * i + 2;
        if (left < size && arr[left] > arr[largest]) largest = left;
        if (right < size && arr[right] > arr[largest]) largest = right;
        if (largest != i) {
            int tmp = arr[i]; arr[i] = arr[largest]; arr[largest] = tmp;
            heapify(arr, size, largest);
        }
    }

    // --------------------------
    // シェルソート
    // --------------------------
    public void shellSort() {
        int n = array.length;
        for (int gap = n / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < n; i++) {
                int temp = array[i];
                int j = i;
                while (j >= gap && array[j - gap] > temp) {
                    array[j] = array[j - gap];
                    j -= gap;
                    updateArray(array);
                }
                array[j] = temp;
                updateArray(array);
            }
        }
    }

    // --------------------------
    // GUI 実行
    // --------------------------
    public static void main(String[] args) {
        int[] initialArray = {7, 2, 9, 4, 3, 8, 1, 6};

        JFrame frame = new JFrame("7種類ソートアニメーション");
        FullSortVisualizerGUI panel = new FullSortVisualizerGUI(initialArray);

        // コントロールパネル
        JPanel controls = new JPanel();
        String[] sorts = {"バブルソート","選択ソート","挿入ソート","マージソート","クイックソート","ヒープソート","シェルソート"};
        JComboBox<String> combo = new JComboBox<>(sorts);
        JButton startButton = new JButton("開始");
        JButton resetButton = new JButton("リセット");
        controls.add(combo);
        controls.add(startButton);
        controls.add(resetButton);

        frame.setLayout(new BorderLayout());
        frame.add(panel, BorderLayout.CENTER);
        frame.add(controls, BorderLayout.SOUTH);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        // ソート開始ボタン
        startButton.addActionListener(e -> {
            panel.array = Arrays.copyOf(panel.originalArray, panel.originalArray.length);
            String sortName = (String) combo.getSelectedItem();
            new Thread(() -> {
                switch (sortName) {
                    case "バブルソート": panel.bubbleSort(); break;
                    case "選択ソート": panel.selectionSort(); break;
                    case "挿入ソート": panel.insertionSort(); break;
                    case "マージソート": panel.mergeSort(); break;
                    case "クイックソート": panel.quickSort(); break;
                    case "ヒープソート": panel.heapSort(); break;
                    case "シェルソート": panel.shellSort(); break;
                }
            }).start();
        });

        // リセットボタン
        resetButton.addActionListener(e -> {
            panel.array = Arrays.copyOf(panel.originalArray, panel.originalArray.length);
            panel.repaint();
        });
    }
}
Java

特徴

  1. 7種類のソートすべて選択可能
  2. 棒グラフでリアルタイムアニメーション
  3. スレッドで非同期実行 → GUI が止まらない
  4. リセットボタン で元の配列に戻せる
  5. 初心者でもソートアルゴリズムの動きを直感的に理解可能
Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました