Java:具有并行数组的快速排序算法



我正在尝试用Java实现快速排序算法:

// Sort parallel arrays with quick sort
import java.util.Scanner;
import java.text.DecimalFormat;
class FunRunQuiSort {
    static int iSize = 5; // Set value
    static double[] daFinishTime = new double[iSize];
    static String[] saRunnerName = new String[iSize];
static void getInput() {
    System.out.println("n***** 5K RUNNERS *****");
    for(int i = 0; i < saRunnerName.length; i++) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter runner name: ");
        saRunnerName[i] = input.nextLine();
        System.out.print("Enter finish time: ");
        daFinishTime[i] = input.nextDouble();
        System.out.print("rn");
    }
}
static void doQuickSort(double[] daFinishTime) {
    int i = daFinishTime[0], j = daFinishTime.length - 1;
    double dTemp;
    String sTemp;
    // Pivot
    double dPivot = daFinishTime[(daFinishTime[0] + daFinishTime.length - 1) / 2];
    // Partition
    do {    
        while(daFinishTime[i] < dPivot) {
            i++;
        } 
        while(daFinishTime[j] > dPivot) {
            j--;
        }
        if(i <= j) {
            dTemp = daFinishTime[i];
            daFinishTime[i] = daFinishTime[j];
            daFinishTime[j] = dTemp;
            sTemp = saRunnerName[i];
            saRunnerName[i] = saRunnerName[j];
            saRunnerName[j] = sTemp;
            i++;
            j--;
        }
    } while(i <= j);
    // Recursion
    if(daFinishTime[0] < j) {
        doQuickSort(daFinishTime, daFinishTime[0], j);
    }
    if(i < daFinishTime.length - 1) {
        doQuickSort(daFinishTime, i, daFinishTime.length - 1);
    }
}
static void printOutput() {
    DecimalFormat df = new DecimalFormat("##.00");
    System.out.println("***** SORTED RUNTIMES *****");
    for(int i = 0; i < daFinishTime.length; i++) {
        System.out.println("[" + (i + 1) + "] " +
            df.format(daFinishTime[i]) + " mins. by " +
            saRunnerName[i]);
    }
    System.out.println("n***** TOP 3 RUNTIMES *****");
    for(int i = 0; i < 3; i++) {
        System.out.println("#" + (i + 1) + " Place: " +
            df.format(daFinishTime[i]) + " mins. by " +
            saRunnerName[i]);
    }
}
public static void main(String[] args) {
    getInput();
    doQuickSort(daFinishTime);
    printOutput();
   }
}

它返回精度损失错误,但当我更改所述行的数据类型时,它返回更多精度损失错误。

有人能修复代码吗?我只需要看看快速排序的作用。

double dPivot = daFinishTime[(daFinishTime[0] + daFinishTime.length - 1) / 2];

如何选择枢轴元素令人困惑。如果你想要中间元素作为支点,它应该是

double dPivot = daFinishTime[(i+j)/2];

在@Tobias解决方案中更新此方法

 static void doQuickSort(double[] daFinishTime, int i, int j) {
        double dTemp;
        String sTemp;
        int start = i;
        int end = j;
        // Pivot
        double dPivot = daFinishTime[(i + j) / 2];
        // Partition
        while (start <= end) {
            while (daFinishTime[start] < dPivot) {
                start++;
            }
            while (daFinishTime[end] > dPivot) {
                end--;
            }
            if (start <= end) {
                dTemp = daFinishTime[start];
                daFinishTime[start] = daFinishTime[end];
                daFinishTime[end] = dTemp;
                sTemp = saRunnerName[start];
                saRunnerName[start] = saRunnerName[end];
                saRunnerName[end] = sTemp;
                start++;
                end--;
            }
        }
        // Recursion
        if (start < j) {
            doQuickSort(daFinishTime, start, j);
        }
        if (i < end) {
            doQuickSort(daFinishTime, i, end);
        }
    }

您已经知道了如何更改快速排序的答案,所以我想介绍一些其他建议和一种稍微不同的方法。我不确定您对拥有两个独立数组的要求是什么,但在我看来,维护这两个数组是一种糟糕的做法——将它们的位置用作标识符。在我看来,你需要一个Runner对象,它可能包含它们的一些细节(如果需要的话)。对于我的示例,我刚刚创建了一个"RunnerTime"对象,它包含两个字段Name(String)和Time(Double)。

然后,我填充了一个Array或RunnerTime对象,以发送到我的quickSort方法中。以下是它的工作原理。

我在当地测试了这一点,增加了4个跑步者:

RunnerTime rt1 = new RunnerTime("Bob", 10.13);
RunnerTime rt3 = new RunnerTime("Craig", 11.65);
RunnerTime rt2 = new RunnerTime("Dave", 11.45);
RunnerTime rt4 = new RunnerTime("Marley", 5.62);

然后我将它们添加到一个数组中,并将它们发送到以下方法:

private static RunnerTime[] doSort(RunnerTime[] runnerTimes) {
        RunnerTime currentRunnerTime;
        RunnerTime nextRunnerTime;
        boolean swapped;
        do {
            swapped = false;
            for (int x = 0; x < runnerTimes.length - 1; x++) {
                currentRunnerTime = runnerTimes[x];
                nextRunnerTime = runnerTimes[x + 1];
                if (currentRunnerTime.time > nextRunnerTime.time) {
                    runnerTimes[x] = nextRunnerTime;
                    runnerTimes[x + 1] = currentRunnerTime;
                    swopped = true;
                }
            }
        } while (swapped);
        return runnerTimes;
    }

完成此操作后,他们排序为:

Runner Name: Marley  Runner Time: 5.62
Runner Name: Bob     Runner Time: 10.13
Runner Name: Dave    Runner Time: 11.45
Runner Name: Craig   Runner Time: 11.65

这样做的好处如下:

  • 你的名字和时间是统一的,所以不可能有一个时间被错误地分配给另一个跑步者
  • 您的排序方法可以短得多,因为您只需要交换一个数组
  • "交换"布尔值意味着你的数组只在需要的时候循环。一旦有一个循环没有进行任何交换(意味着每个人都有序),循环就会退出

如果可能,请参阅实现快速排序算法。此外,为什么要在程序中使用int和doubles呢。由于代码上的注释状态正确,因此程序无法编译。

我对doQuick排序方法做了一些更改。现在它正在编译,而且似乎起作用了。

// Sort parallel arrays with quick sort
import java.text.DecimalFormat;
import java.util.Scanner;
class FunRunQuiSort {
static int iSize = 5; // Set value
static double[] daFinishTime = new double[iSize];
static String[] saRunnerName = new String[iSize];
static void getInput() {
    System.out.println("n***** 5K RUNNERS *****");
    for(int i = 0; i < saRunnerName.length; i++) {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter runner name: ");
        saRunnerName[i] = input.nextLine();
        System.out.print("Enter finish time: ");
        daFinishTime[i] = input.nextDouble();
        System.out.print("rn");
    }
}
static void doQuickSort(double[] daFinishTime, int i, int j) {
    double dTemp;
    String sTemp;
    // Pivot
    double dPivot = daFinishTime[(i + j) / 2];
    // Partition
    while(i <= j) {
        while(daFinishTime[i] < dPivot) {
            i++;
        } 
        while(daFinishTime[j] > dPivot) {
            j--;
        }
        if(i <= j) {
            dTemp = daFinishTime[i];
            daFinishTime[i] = daFinishTime[j];
            daFinishTime[j] = dTemp;
            sTemp = saRunnerName[i];
            saRunnerName[i] = saRunnerName[j];
            saRunnerName[j] = sTemp;
            i++;
            j--;
        }
    }
    // Recursion
    if(i < i - 1) {
        doQuickSort(daFinishTime, i, i - 1);
    }
    if(i < j) {
        doQuickSort(daFinishTime, i, j);
    }
}
static void printOutput() {
    DecimalFormat df = new DecimalFormat("##.00");
    System.out.println("***** SORTED RUNTIMES *****");
    for(int i = 0; i < daFinishTime.length; i++) {
        System.out.println("[" + (i + 1) + "] " +
                df.format(daFinishTime[i]) + " mins. by " +
                saRunnerName[i]);
    }
    System.out.println("n***** TOP 3 RUNTIMES *****");
    for(int i = 0; i < 3; i++) {
        System.out.println("#" + (i + 1) + " Place: " +
                df.format(daFinishTime[i]) + " mins. by " +
                saRunnerName[i]);
    }
}
public static void main(String[] args) {
        getInput();
        doQuickSort(daFinishTime, 0, daFinishTime.length - 1);
        printOutput();
    }
}

最新更新