java sorting

来源:互联网 发布:python数据库 编辑:程序博客网 时间:2024/05/21 13:59
import java.awt.Dimension;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.util.Arrays;import java.util.Random;import javax.swing.*;/** * A class containing a number of classic sorting algorithms, * implemented from scratch.  The algorithms each operate on arrays * of ints only, and are animated. */public class Sorter extends JPanel {     private static Random randomizer = new Random();    private static final int ARRAY_LENGTH = 600;    private static final int MAX_VALUE = 400;    private final int[] array = new int[ARRAY_LENGTH];    private transient boolean shouldStop = false;            /**     * Swaps a[i] and a[j].     */    private void swap(int[] a, int i, int j) {        int old = a[i];        a[i] = a[j];        a[j] = old;    }    /**     * Fills an array with random values between 0 and MAX_VALUE.     */    private void reload(int[] a) {        for (int i = 0; i < a.length; i++) {            a[i] = randomizer.nextInt(MAX_VALUE);        }    }    /**     * Sorts an array using Selection Sort.  The algorithm is to first     * put the smallest item in the first position, then the next     * smallest in the second position, and so on.     */    public void selectionSort(int[] a) {        for (int i = 0; i < a.length - 1; i++) {            int small = i;            for (int j = i + 1; j < a.length; j++) {                if (a[j] < a[small]) small = j;                PAUSE();            }            swap(a, i, small);        }    }    /**     * Sorts an array using Insertion Sort.  The algorithm is to first     * slide the second element back as far as it should go, then slide     * the third back, and so on.     */    public void insertionSort(int[] a) {        for (int i = 1; i < a.length; i++) {            int current = a[i];            int j = i;            for (; j > 0 && current < a[j-1]; j--) {                a[j] = a[j-1];                PAUSE();            }            a[j] = current;        }    }    /**     * Sorts an array using Bubble Sort.     */    public void bubbleSort(int[] a) {        for (int i = a.length - 1; i > 0; i--) {            for (int j = 0; j < i; j++) {                if (a[j] > a[j + 1]) swap(a, j, j + 1);                PAUSE();            }        }    }    /**     * Sorts an array using Gnome Sort.     */    public void gnomeSort(int[] a) {        for (int i = 0; i < a.length;) {            PAUSE();            if (i == 0 || a[i-1] <= a[i]) {                i++;            } else {                swap(a, i, i - 1);                i--;            }        }    }    /**     * Sorts an array using Shell Sort.  This is a lousy Shell Sort.     * I need to make a new one.     */    public void shellSort(int[] a) {        int distance = a.length / 2;        while (distance > 0) {            boolean changed = false;            for (int i = 0; i < a.length - distance; i++) {            if (a[i] > a[i + distance]) {                swap(a, i, i + distance);                changed = true;            }                PAUSE();            }            if (!changed) distance /= 2;        }    }    /**     * Sorts an array using Quick Sort.  This version of quicksort uses     * the leftmost item as the pivot, but since this gives disastrous     * performance on sorted and nearly sorted arrays, we scramble the     * array first.     */    public void quickSort(int[] a) {        // First shuffle (permute) the array        for (int i = 0; i < a.length; i++) {            swap(a, i, randomizer.nextInt(ARRAY_LENGTH));        }                // Call the recursive helper        quickSort(a, 0, a.length - 1);    }    private void quickSort(int[] a, int left, int right) {        if (left < right) {            int i = left;            int j = right;            while (i < j) {                while (a[j] > a[left]) {j--; PAUSE();}                 while (i < j && a[i] <= a[left]) {i++; PAUSE();}                 if (i < j) swap(a, i, j);            }            swap(a, left, j);            quickSort(a, left, j-1);            quickSort(a, j+1, right);        }    }    /**     * Sorts an array using Heap Sort.     */    public void heapSort(int[] a) {        // Phase 1: make a heap by sifting down all non-leaf         // elements, one after another, starting with the last        // non-leaf element and going backwards.        for (int i = a.length / 2 - 1; i >= 0; i--) {            for (int j = i; j * 2 + 1 < a.length;) {                PAUSE();                int k = j * 2 + 1;                if (k + 1 < a.length && a[k] < a[k + 1]) k++;                if (a[j] < a[k]) swap(a, j, k); else break;                j = k;            }        }        // Phase 2: Successively place the biggest, then next biggest        // items at the end of the array. each time reconstructing the        // heap in the slots of the array not yet sorted.        for (int i = a.length - 1; i > 0; i--) {            swap(a, 0, i);            for (int j = 0; j * 2 + 1 < i;) {                PAUSE();                int k = j * 2 + 1;                if (k + 1 < i && a[k] < a[k + 1]) k++;                if (a[j] < a[k]) swap(a, j, k); else break;                j = k;            }        }    }        /**     * Sorts an array using merge sort, the classic version with     * the extra storage.     */    public void mergeSort(int[] a) {        int[] scratch = new int[a.length];        mergeSort(a, 0, a.length - 1, scratch);    }        private void mergeSort(int[] a, int lo, int hi, int[] scratch) {        if (lo >= hi) return;                int mid = (lo + hi) / 2;        mergeSort(a, lo, mid, scratch);        mergeSort(a, mid + 1, hi, scratch);        // Merge sorted sublists into temporary storage        for (int i = lo, j = mid + 1, k = lo; k <= hi; k++) {            if ((i <= mid) && ((j > hi) || (a[i] < a[j]))) {                scratch[k] = a[i++]; PAUSE();             } else {                scratch[k] = a[j++]; PAUSE();             }         }                // Copy back from temporary storage        for (int k = lo; k <= hi; k++) {             a[k] = scratch[k]; PAUSE();         }        }        /**     * Sorts an array using counting sort, provided all values in the     * array are non-negative.  If there are negative values in the array,     * the method will not sort but rather leave the array undefined.     * Furthermore, the method will likely throw an OutOfMemoryError     * if there are large integers in the array.     */    public void countingSort(int[] a) {        int max = 0;        for (int i = 0; i < a.length; i++) {            max = Math.max(max, a[i]);            PAUSE();                }        System.out.println(max);        int[] counts = new int[max + 1];        Arrays.fill(counts, 0);        for (int i = 0; i < a.length; i++) {            counts[a[i]]++;            PAUSE();        }        for (int i = 0, j = 0; j < counts.length; j++) {            for (int k = 0; k < counts[j]; k++) {                a[i++] = j;                PAUSE();             }        }    }        public static void main(String[] args) {        Sorter sorter = new Sorter();        JFrame frame = new JFrame("Sorting");        frame.getContentPane().add(sorter.toolbar, "North");        frame.getContentPane().add(sorter, "Center");        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.pack();        frame.setVisible(true);        sorter.runAnimation();    }    Action startAction = new AbstractAction("Start") {        public void actionPerformed(ActionEvent e) {            final String methodName = (String)comboBox.getSelectedItem();            new Thread(new Runnable() {                public void run() {                startButton.setEnabled(false);                stopButton.setEnabled(true);                reload(array);                try {                    Sorter.class.getMethod(methodName,                         new Class[]{array.getClass()})                        .invoke(Sorter.this, new Object[]{array});                } catch (Exception e) {                }                stopButton.setEnabled(false);                startButton.setEnabled(true);            }}        ).start();    }    };    Action stopAction = new AbstractAction("Stop") {        public void actionPerformed(ActionEvent e) {            shouldStop = true;            }    };        private JToolBar toolbar = new JToolBar();    private JButton startButton = new JButton(startAction);    private JButton stopButton = new JButton(stopAction);    JComboBox comboBox = new JComboBox(new String[]{        "selectionSort",        "insertionSort",        "bubbleSort",        "gnomeSort",        "shellSort",        "quickSort",        "mergeSort",        "heapSort",        "countingSort"    });        public Sorter() {        setPreferredSize(new Dimension(ARRAY_LENGTH, MAX_VALUE));        setBorder(BorderFactory.createEtchedBorder());        toolbar.add(comboBox);        toolbar.add(startButton);        toolbar.add(stopButton);        comboBox.setMaximumRowCount(12);    }    protected void paintComponent(Graphics g) {        super.paintComponent(g);        for (int i = 0, n = array.length; i < n; i++) {            g.drawLine(i, MAX_VALUE, i, MAX_VALUE - array[i]);        }    }        /**     * Causes the screen to be repainted every 30 ms or so.     */    private void runAnimation() {        while (true) {            repaint();            try {Thread.sleep(30);} catch (InterruptedException e) {}        }    }    /**     * Something to call periodically during sorting.     */        private void PAUSE() {        try {            Thread.sleep(1);            if (shouldStop) {                shouldStop = false;                // Can't think of a better way to stop than this                throw new RuntimeException();            }        } catch (InterruptedException e) {        }    }}
原创粉丝点击