簡體   English   中英

如何修復此 Java 冒泡排序算法?

[英]How do I fix this Java BubbleSort algorithm?

我正在做一個 Java 編程作業,其中涉及對 a.dat 文件 BetelgeuseNames.dat 進行氣泡排序,其中包含按字母順序排列的字符串。 我的 AP Computer Science 一位老師告訴我我的代碼是正確的,但它仍然給出了錯誤的 output。

共有三個類,分別稱為 BubbleSort、BubbleSortTimer 和 StopWatch。 該程序從 BubbleSortTimer 運行。

冒泡排序:

import java.util.ArrayList;
import javax.swing.JOptionPane;
import java.io.FileWriter;
import java.io.IOException;

public class BubbleSort {

// Private instance variables:
    private ArrayList<String> list;
    private int number;

    public BubbleSort(ArrayList<String> a_list) {
        list = a_list;
    }

    public void swap(int first, int second) {
        String temp1 = list.get(first);
        String temp2 = list.get(second);
        list.set(first, temp2);
        list.set(second, temp1);

    }

    public int getNumber() {
        String numStr;
        numStr = JOptionPane.showInputDialog("How many names do you want to sort?");
        number = Integer.parseInt(numStr);
        return number;
    }

    public void printSorted() {
        try {
            FileWriter writer = new FileWriter("sorted.dat");
            for (int i = 0; i < number; i++) {
                writer.write(list.get(i) + "\n");
            }
            writer.close();
        } catch (IOException exception) {   
            System.out.println("Error processing file: " + exception);
        }
    }

    public void bubbleSort() {
        for (int i = 0; i < number; i++) {
            for (int j = 0; j < number - i - 1; j++) {
                if (list.get(i).compareTo(list.get(i+1)) > 0) {
                    swap(i, i + 1);
                }
            }
        }
    } // End method
}

冒泡排序定時器:

import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.FileReader;
import javax.swing.JOptionPane;
import java.io.IOException;

public class BubbleSortTimer {

    private ArrayList<String> list = new ArrayList<String>();

    public void readNames() {
        try {   
            FileReader reader = new FileReader("BetelgeuseNames.dat");  
            BufferedReader in = new BufferedReader(reader);
            boolean done = false;
            String name;
            while (done == false) {
                name = in.readLine();
                if (name == null) {
                    done = true;
                } else {
                    list.add(name);
                }
            }
            reader.close();
        } catch (IOException exception) {   
            System.out.println("Error processing file: " + exception);
        }
    } // End method

    public void runSort() {
        readNames();
        StopWatch timer = new StopWatch();
        BubbleSort sorter = new BubbleSort(list);
        int number = sorter.getNumber();
        timer.start();
        sorter.bubbleSort();
        timer.stop();
        sorter.printSorted();
        String msg = "Number of names sorted: " + number + "\nMilliseconds required to sort: " + timer.getElapsedTime() + "\nOutput file is \"sorted.dat\"";
        JOptionPane.showMessageDialog(null, msg);
    }
        
    public static void main(String[] args) {
        BubbleSortTimer bubble = new BubbleSortTimer();
        bubble.runSort();
    }
}

跑表:

/**
 * A stopwatch accumulates time when it is running.  You can 
 * repeatedly start and stop the stopwatch.  You can use a
 * stopwatch to measure the running time of a program.
 * from section 18.2 of Horstmann's CCJ
 */
public class StopWatch {
    /**
     * Constructs a stopwatch that is in the stopped state
     * and has no time accumulated.
     */
    public StopWatch() {
        reset();
    }
    
    /**
    * Starts the stopwatch.  Times starts accumulating now.
    */
    public void start() {       
        if (isRunning) return;
        isRunning = true;
        startTime = System.currentTimeMillis();     
    }
    
    /**
    * Stops the stopwatch.  Time stops accumulating and is 
    * added to the elapsed time.
    */
    public void stop() {    
        if (!isRunning) return;
        isRunning = false;
        long endTime = System.currentTimeMillis();
        elapsedTime = elapsedTime + endTime - startTime;
    }
    
    /**
    * Returns the total elapsed time.
    @return the total elapsed time
    */
    public long getElapsedTime() {  
        if (isRunning) {    
            long endTime = System.currentTimeMillis();
            elapsedTime = elapsedTime + endTime - startTime;
            startTime = endTime;
        }
        return elapsedTime;
    }
        
    /**
     * Stops the watch and resets the elapsed time to 0.
     */
    public void reset() {   
        elapsedTime = 0;
        isRunning = false;
    }       

    private long elapsedTime;
    private long startTime;
    private boolean isRunning;

}

輸入:

Moewm
Bmlzvltcso
Aqxjor
Wwgjie
Qqqtpivd
Xgyhaerv
Wqpjwdvxjq
Ecsfnow
Zlptuqxctt
Jhtprwvopk

預期 Output:

Aqxjor
Bmlzvltcso
Ecsfnow
Jhtprwvopk
Moewm
Qqqtpivd
Wqpjwdvxjq
Wwgjie
Xgyhaerv
Zlptuqxctt

實際 Output:

Bmlzvltcso
Aqxjor
Moewm
Qqqtpivd
Wwgjie
Wqpjwdvxjq
Ecsfnow
Xgyhaerv
Jhtprwvopk
Zlptuqxctt

這就是 Android 進行(二進制)排序的方式(編輯以解決這種情況):

public void binarySort() {
    int lo = 0; // sort start
    for (int start=lo ; start < number; start++) {
        String pivot = list.get(start);

        // Set left (and right) to the index where list.get(start) (pivot) belongs
        int left = 0;
        int right = start;
        assert left <= right;
        /*
         * Invariants:
         *   pivot >= all in [lo, left].
         *   pivot <  all in [right, start].
         */
        while (left < right) {
            int mid = (left + right) >>> 1;
            if (pivot.compareTo(list.get(mid)) < 0)
                right = mid;
            else
                left = mid + 1;
        }
        assert left == right;

        /*
         * The invariants still hold: pivot >= all in [lo, left] and
         * pivot < all in [left, start], so pivot belongs at left.  Note
         * that if there are elements equal to pivot, left points to the
         * first slot after them -- that's why this sort is stable.
         * Slide elements over to make room for pivot.
         */
        int n = start - left;  // The number of elements to move
        // Switch is just reshifter in default case
        switch (n) {
            case 2:  list.set(left + 2,list.get(left + 1));
            case 1:  list.set(left + 1,list.get(left));
                break;
            default: 
            if(n>0){
                list.add(left,list.remove(left+n));
            }
        }
        list.set(left,pivot);
    }
}

這是您可以進行(冒泡)排序的方法:

public void bubbleSort() {
    for (int i = 0; i < number; i++) {
        for (int j = i + 1; j < number; j++) {
            if (list.get(i).compareTo(list.get(j)) > 0) {
                swap(i, j);
            }
        }
    }
}

冒泡排序 V/S 二進制排序:

題外話:正如您在上面比較的那樣,冒泡排序更容易編碼/閱讀/理解,並且與二進制排序相比也更快,因為二進制排序(實際上)多次使用數組重新創建,這與交換相比當然需要更多時間。

因為你的bubbleSort()方法有問題。 請嘗試這種方式。

public void bubbleSort() {
    for (int i = 0; i < number; i++) {
        for (int j = 1; j < number - i; j++) {
            if (list.get(j - 1).compareTo(list.get(j)) > 0) {
                swap(j - 1, j);
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM