java sorting

    技术2022-05-11  2

    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) { } } }  

    最新回复(0)