简体   繁体   English

Java:具有并行数组的Quicksort算法

[英]Java: Quicksort algorithm with parallel arrays

I am trying to implement the quicksort algorithm in Java: 我试图在Java中实现quicksort算法:

// 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("\r\n");
    }
}

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();
   }
}

It is returning loss of precision errors, but when I change the data type of the said line, it returns more loss of precision errors. 它返回精度错误的丢失,但是当我更改所述行的数据类型时,它返回更多的精度错误。

Can someone fix the code? 有人可以修复代码吗? I just need to see the quicksort in action. 我只需要看看快速排序的实际效果。

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

How you are selecting pivot element is confusing. 如何选择枢轴元素令人困惑。 if you want mid element as pivot, it should be 如果你想将mid元素作为pivot,它应该是

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

Update this method in @Tobias solution 在@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);
        }
    }

You had answers of how to change your quick-sort so I thought I'd introduce a few other suggestions and a slightly different approach. 您有如何更改快速排序的答案,所以我想我会介绍一些其他建议和略有不同的方法。 I'm not sure what your requirements for having two separate arrays are but it seems to me like bad practice maintaining the two - using their positions as identifiers. 我不确定你对两个独立阵列的要求是什么,但在我看来,这就像保持两者的不良做法一样 - 使用它们的位置作为标识符。 In my opinion, you need a Runner object, which perhaps contains some of their details (if needed). 在我看来,你需要一个Runner对象,它可能包含一些细节(如果需要)。 For my example, I've just created a 'RunnerTime' object which contains the two fields Name(String) and Time(Double). 对于我的例子,我刚刚创建了一个'RunnerTime'对象,它包含两个字段Name(String)和Time(Double)。

I'v then populated an Array or RunnerTime objects to send into my quickSort method. 然后,我将填充一个Array或RunnerTime对象以发送到我的quickSort方法。 Here is how it works. 下面是它的工作原理。

I've tested this out locally adding 4 runners: 我在本地测试了这个,增加了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);

I've then added them to an array and sent them to the following method: 然后我将它们添加到一个数组并将它们发送到以下方法:

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;
    }

After doing this they sorted to: 完成后,他们排序为:

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

The advantages of doing it this way are as follows: 这样做的好处如下:

  • Your name and time are united, so there's no chance of a time being mistakenly assigned so another runner. 你的名字和时间是统一的,所以没有时间错误地分配给另一个跑步者。
  • Your sort method can be much shorter as you only need to swap one array. 您的排序方法可以更短,因为您只需要交换一个数组。
  • The 'swapped' boolean means that your array is only looped through as many times as it needs to. 'swapped'布尔意味着你的数组只需要循环多次。 Once there's has been a cycle that has not made any swaps (meaning that everyone is in order) - the loop will exit. 一旦有一个没有进行任何交换的周期(意味着每个人都在按顺序) - 循环将退出。

If Possible Refer to Implementing quicksort algorithm . 如果可能请参阅实施快速排序算法 Moreover why are you complicating with ints and doubles in the program.As the comments on your code state correctly your program doesnt compile because of that. 此外,为什么你在程序中使用int和double复杂化。由于对代码的注释正确,因此你的程序无法编译。

I've made some changes in the doQuickSort-method. 我在doQuickSort方法中做了一些改动。 Now its compiling, and it seems to work. 现在它的编译,似乎工作。

// 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("\r\n");
    }
}

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM