//Änderungen zur Originalversion // - neu überladene Grafikroutine ShowArray, jetzt mit Image zum Buffern // - in jeder do...Sort Methode: // * Image bild initialisiert // * den Aufruf von ShowArray ersetzt // - void RekQuickSort(Graphics g, int[] A, int Lo, int Hi) // ersetzt durch // void RekQuickSort(Graphics g, int[] A, int Lo, int Hi, Image bild) // - About-Dialog angepasst import java.awt.*; import java.io.*; import java.util.*; import java.awt.event.*; class SortAnimation extends Frame{ private static final String VersionsDatum ="17. April 2000"; private static String Titel = "Sortier Animation"; private static int WarteZeit = 0; // default private final static int Anzahl = 1000; private final static ArrayGen AG = new ArrayGen(Anzahl); private static final Font FontMono = new Font("Monospaced", Font.PLAIN, 20); private static final Font FontSansSerif = new Font("SansSerif", Font.PLAIN, 18); private static final Font BigItalicSansSerif = new Font("SansSerif", Font.ITALIC, 20); private static MenuBar MainMenuBar = new MenuBar(); private static Menu DateiMenu = new Menu("Datei"); private static MenuItem Beenden = new MenuItem("Beenden"); private static Menu SortMenu = new Menu("Sort"); private static MenuItem BubbleSortM = new MenuItem("BubbleSort"); private static MenuItem SelectionSortM = new MenuItem("SelectionSort"); private static MenuItem InsertionSortM = new MenuItem("InsertionSort"); private static MenuItem ShellSortM = new MenuItem("ShellSort"); private static MenuItem QuickSortM = new MenuItem("QuickSort"); private static MenuItem HeapSortM = new MenuItem("HeapSort"); private static MenuItem DistributionSortM = new MenuItem("DistributionSort"); private static Menu OptionenMenu = new Menu("Optionen"); private static MenuItem Optio1 = new MenuItem("Ohne Verzögerung"); private static MenuItem Optio2 = new MenuItem("Verzögerung 50 mS"); private static MenuItem Optio3 = new MenuItem("Verzögerung 150 mS"); private static MenuItem Optio4 = new MenuItem("Verzögerung 300 mS"); private static Menu HilfeMenu = new Menu("Hilfe"); private static MenuItem Hilfe = new MenuItem("Es gibt keine Hilfe..."); private static MenuItem AboutBox = new MenuItem("About"); //// Constructor. public SortAnimation () { super(Titel); setFont(FontMono); DateiMenu.setFont(FontSansSerif); Beenden.setFont(FontSansSerif); SortMenu.setFont(FontSansSerif); BubbleSortM.setFont(FontSansSerif); SelectionSortM.setFont(FontSansSerif); InsertionSortM.setFont(FontSansSerif); ShellSortM.setFont(FontSansSerif); QuickSortM.setFont(FontSansSerif); HeapSortM.setFont(FontSansSerif); DistributionSortM.setFont(FontSansSerif); OptionenMenu.setFont(FontSansSerif); Optio1.setFont(FontSansSerif); Optio2.setFont(FontSansSerif); Optio3.setFont(FontSansSerif); Optio4.setFont(FontSansSerif); HilfeMenu.setFont(FontSansSerif); Hilfe.setFont(FontSansSerif); AboutBox.setFont(FontSansSerif); setLayout(null); //// Menüs setMenuBar(MainMenuBar); MainMenuBar.add(DateiMenu); DateiMenu.addSeparator(); DateiMenu.add(Beenden); MainMenuBar.add(SortMenu); SortMenu.add(BubbleSortM); SortMenu.add(SelectionSortM); SortMenu.add(InsertionSortM); SortMenu.add(ShellSortM); SortMenu.add(QuickSortM); SortMenu.add(HeapSortM); SortMenu.add(DistributionSortM); MainMenuBar.add(OptionenMenu); OptionenMenu.add(Optio1); OptionenMenu.add(Optio2); OptionenMenu.add(Optio3); OptionenMenu.add(Optio4); MainMenuBar.add(HilfeMenu); HilfeMenu.add(Hilfe); HilfeMenu.addSeparator(); HilfeMenu.add(AboutBox); //// Allgemeine Initialisierung //doDateiNeu(); //// Menü Listener Beenden.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ FensterBeenden(); } }); BubbleSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doBubbleSort(); } }); SelectionSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doSelectionSort(); } }); InsertionSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doInsertionSort(); } }); ShellSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doShellSort(); } }); QuickSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doQuickSort(); } }); HeapSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doHeapSort(); } }); DistributionSortM.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ doDistributionSort(); } }); Optio1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ WarteZeit = 0; } }); Optio2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ WarteZeit = 50; } }); Optio3.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ WarteZeit = 150; } }); Optio4.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ WarteZeit = 300; } }); AboutBox.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ showAboutBox(); } }); //// Window Listener addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { FensterBeenden(); } }); //// Jetzt Fenster zeigen! //setBackground(Color.lightGray); setSize(1000,740); setVisible(true); } //// Ende des Konstruktors //// Grafik Routinen /*private void ShowArray(Graphics g, int[] A, int Lo, int Hi){ Dimension d = getSize(); int XMax = d.width; int YMax = d.height; if (Hi > XMax) Hi = XMax; //System.out.println(XMax+" "+YMax+" "+Lo+" "+Hi); int YMitte = YMax/2; g.clearRect(Lo, 0, Hi, YMax); g.setColor(Color.black); for (int i = Lo; i <= Hi; i++){ int YVal = A[i]; //System.out.println(i+" "+YVal); g.drawLine(i, YMitte+YVal, i, YMitte-YVal); } if (WarteZeit > 0){ // Mach mal Pause long t = WarteZeit + System.currentTimeMillis(); while(System.currentTimeMillis() < t); } }*/ private void ShowArray(Graphics g, int[] A, int Lo, int Hi, Image bild) { //Thomas Horstmeyer Graphics gbild=bild.getGraphics(); Dimension d=getSize(); int XMax=d.width; int YMax = d.height; if (Hi > XMax) Hi = XMax; int YMitte=(int) getHeight()/2; gbild.clearRect(Lo, 0, Hi, YMax); gbild.setColor(Color.black); //folgende zwei Zeilen statt der obigen zwei helfen vielleicht beim debuggen (QuickSort) //Random r=new Random(System.currentTimeMillis()); //gbild.setColor(new Color(r.nextInt())); for(int i=Lo; i<=Hi; i++) { int YVal=A[i]; gbild.drawLine(i, YMitte+YVal, i, YMitte-YVal); } g.drawImage(bild, 0, 0, null); if (WarteZeit > 0){ // Mach mal Pause long t = WarteZeit + System.currentTimeMillis(); while(System.currentTimeMillis() < t); } } //// Swap und minPos private static void Swap(int[] A, int i, int k){ int h = A[i]; A[i] = A[k]; A[k] = h; } private static int minPos(int[] A, int Lo, int Hi){ int Min = Lo; for (int i = Lo+1; i <= Hi; i++) if (A[i] < A[Min]) Min = i; return Min; } //// Es folgen: Die Sortier Routinen void doBubbleSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; ShowArray(g, A, 0, Hi, bild); for (int k = Hi; k > 0; k--){ boolean test = true; for (int i = 0; i < k; i++) if ( A[i] > A[i+1]) { Swap (A, i, i+1); test = false;} ShowArray(g, A, 0, k, bild); if (test) break; } } void doSelectionSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; ShowArray(g, A, 0, Hi, bild); for (int k = 0; k < Hi; k++){ int Min = minPos(A, k, Hi); if ( Min != k) Swap (A, Min, k); ShowArray(g, A, k, Hi, bild); } } void doInsertionSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; ShowArray(g, A, 0, Hi, bild); for (int k = 1; k <= Hi; k++){ if (A[k] < A[k-1]){ int x = A[k]; int i; for ( i = k; ( (i > 0) && (A[i-1] > x) ) ; i-- ) A[i] = A[i-1]; A[i] = x; } ShowArray(g, A, 0, Hi, bild); } } void doShellSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; ShowArray(g, A, 0, Hi, bild); int hmax, h ; for ( hmax = 1; hmax < Hi ; hmax = 3*hmax+1 ); for ( h = hmax/3; h > 0; h /= 3) for (int k = h; k <= Hi; k++){ if (A[k] < A[k-h]){ int x = A[k]; int i; for ( i = k; ( (i > (h-1)) && (A[i-h] > x) ) ; i-=h ) A[i] = A[i-h]; A[i] = x; } ShowArray(g, A, 0, Hi, bild); } } void doQuickSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; RekQuickSort(g, A, 0, Hi, bild); ShowArray(g, A, 0, Hi, bild); } void RekQuickSort(Graphics g, int[] A, int Lo, int Hi, Image bild){ //ShowArray(g, A, Lo, Hi, bild); int li = Lo; int re = Hi; int mid = (li+re)/2; if (A[li] > A[mid]) Swap(A, li, mid); if (A[mid] > A[re]) Swap(A, mid, re); if (A[li] > A[mid]) Swap(A, li, mid); // <= 3 Elemente haben wir schon sortiert ! // > 3 Elemente müssen noch sortiert werden ! if ((re - li) > 2){ int w = A[mid]; do{ while (A[li] < w) li++; while (w < A[re]) re--; if (li <= re){ Swap(A, li, re); li++; re--;} }while (li <= re); if (Lo < re) { ShowArray(g, A, Lo, re, bild); RekQuickSort(g, A, Lo, re, bild); } if (li < Hi) { ShowArray(g, A, li, Hi, bild); RekQuickSort(g, A, li, Hi, bild); } } } void DownHeap(int[] A, int i, int m){ int sonny = 2*i + 1; while (sonny <= m){ if ((sonny < m) && (A[sonny] < A[sonny+1])) sonny++; // Linker oder rechter Zweig if (A[i] < A[sonny]) { // tauschen ? Swap(A, i, sonny); i = sonny; sonny += sonny + 1; } else break; } } void doHeapSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; ShowArray(g, A, 0, Hi, bild); for (int i = Hi/2; i >= 0; i--) { DownHeap(A, i, Hi); ShowArray(g, A, 0, Hi, bild); } for (int i = Hi; i > 0; i--) { Swap(A, i, 0); DownHeap(A, 0, i-1); ShowArray(g, A, 0, Hi, bild); } } void doDistributionSort(){ int [] A; A = AG.ArrayKopie(); Graphics g = getGraphics(); Image bild=createImage(getWidth(), getHeight()); //Bild zum Buffern int Hi = A.length-1; ShowArray(g, A, 0, Hi, bild); int[] B = new int[Hi+1]; int[] Count = new int[256]; // per default mit 0 initialisiert // Byte 1 By1(x) = (x & 0xff) //for (int i=0; i < 256; i++) Count[i] = 0; for (int i=0; i <= Hi; i++) // Zählen Count[ A[i] & 0xff]++; for (int i=1; i < 256; i++) // Aufsummieren Count[i] += Count[i-1]; for (int i = Hi; i >= 0; i--) // Verteilen B[--Count[A[i]& 0xff]] = A[i]; // for (int i=0; i <= Hi; i++) A[i] = B[i]; System.arraycopy(B, 0, A, 0, Hi+1); ShowArray(g, A, 0, Hi, bild); // Byte 2 By2(x) = ((x >> 8) & 0xff) for (int i=0; i < 256; i++) Count[i] = 0; for (int i=0; i <= Hi; i++) // Zählen Count[ (A[i] >> 8) & 0xff]++; for (int i=1; i < 256; i++) // Aufsummieren Count[i] += Count[i-1]; for (int i = Hi; i >= 0; i--) // Verteilen B[--Count[(A[i] >> 8) & 0xff]] = A[i]; // for (int i=0; i <= Hi; i++) A[i] = B[i]; System.arraycopy(B, 0, A, 0, Hi+1); ShowArray(g, A, 0, Hi, bild); // Byte 3 By3(x) = ((x >> 16) & 0xff) for (int i=0; i < 256; i++) Count[i] = 0; for (int i=0; i <= Hi; i++) // Zählen Count[ (A[i] >> 16) & 0xff]++; for (int i=1; i < 256; i++) // Aufsummieren Count[i] += Count[i-1]; for (int i = Hi; i >= 0; i--) // Verteilen B[--Count[(A[i] >> 16) & 0xff]] = A[i]; // for (int i=0; i <= Hi; i++) A[i] = B[i]; System.arraycopy(B, 0, A, 0, Hi+1); // Byte 4 By4(x) = ((x >> 24) & 0xff) for (int i=0; i < 256; i++) Count[i] = 0; for (int i=0; i <= Hi; i++) // Zählen Count[ (A[i] >> 24) & 0xff]++; for (int i=1; i < 256; i++) // Aufsummieren Count[i] += Count[i-1]; for (int i = Hi; i >= 0; i--) // Verteilen B[--Count[(A[i] >> 24) & 0xff]] = A[i]; // for (int i=0; i <= Hi; i++) A[i] = B[i]; System.arraycopy(B, 0, A, 0, Hi+1); ShowArray(g, A, 0, Hi, bild); } //// Implementierung der übrigen Menü Befehle //// About Box void showAboutBox(){ final Frame f = new Frame("About Box"); final Button Ok = new Button("Ok"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { f.dispose(); } }); Ok.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { f.dispose(); } }); f.setFont(BigItalicSansSerif); f.setLayout(new GridLayout(0, 1)); f.add(new Label(" ", Label.CENTER)); f.add(new Label("Universität Marburg - Fachbereich Mathematik und Informatik", Label.CENTER)); f.add(new Label("Informatik II a Vorlesung Sommersemester 2000", Label.CENTER)); f.add(new Label("Teilprojekt: Sortier Animation", Label.CENTER)); f.add(new Label("Datum der letzten Änderung: " + VersionsDatum, Label.CENTER)); f.add(new Label("Autor: Prof. Dr. Manfred Sommer", Label.CENTER)); f.add(new Label("Grafikroutine überarbeitet von Thomas Horstmeyer", Label.CENTER)); f.add(new Label(" ", Label.CENTER)); f.add(Ok); f.pack(); f.setVisible(true); } //// Programm Beenden void FensterBeenden() { dispose(); System.exit(0); } //// Programm Starten public static void main(String args[]) { new SortAnimation (); } }