简体   繁体   English

使用比较器进行快速排序

[英]Quicksort With a Comparator

i'am working on project to Sort an array of Student objects with the following critiria: 我正在研究对具有以下条件的Student对象进行排序的项目:

1.Sort grades 1,成绩等级

2.If grades are equal, sort on StudentNumber. 2.如果成绩相等,请按学生编号排序。

now i got this working using the Arrays.Sort(T[] a, Comparator<> c ) method. 现在我使用Arrays.Sort(T [] a,Comparator <> c)方法进行了这项工作。 since i think this sorting method is to slow, i want to use Quicksort. 因为我认为这种排序方法很慢,所以我想使用Quicksort。

i got the following piece of code: 我得到以下代码:

public static void quickSort(Student[] arr, int low, int high) {
    if (arr == null || arr.length == 0) {
        return;
    }
    if (low >= high) {
        return;
    }
    // pick the pivot
    int middle = low + (high - low) / 2;
    Student pivot = arr[middle];
    // make left < pivot and right > pivot
    int i = low, j = high;
    while (i <= j) {
        while (arr[i].getCijfer() < pivot.getCijfer()) {
            i++;
        }
        while (arr[j].getCijfer() > pivot.getCijfer()) {
            j--;
        }
        if (i <= j) {
            Student temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    // recursively sort two sub parts
    if (low < j) {
        quickSort(arr, low, j);
    }
    if (high > i) {
        quickSort(arr, i, high);
    }
}

UPDATE Comparator Code: UPDATE比较器代码:

private static Comparator<Student> gradeComparator = new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        int compareTo = 0;
        if (o1.cijfer > o2.cijfer) {
            compareTo = -1;
        } else {
            if (o1.cijfer < o2.cijfer) {
                compareTo = 1;
            } else {
                // als Studenten Grade gelijk, vergelijk op studenten Ldap
                if (o1.cijfer == o2.cijfer) {
                    if (o1.studentnummer > o2.studentnummer) {
                        compareTo = -1;
                    } else {
                        compareTo = 1;
                    }
                }
            }
        }
        return compareTo;
    }
};

this sorts the array on the Grades(cijfer) but i'am stuck on where to put my 2nd sorting criteria. 这对成绩(cijfer)上的数组进行排序,但我被困在哪里放置我的第二个排序标准。 please help me! 请帮我!

Kind regards 亲切的问候

This expression: arr[i].getCijfer() < pivot.getCijfer() and this: arr[j].getCijfer() > pivot.getCijfer() are the source of your problem. 该表达式: arr[i].getCijfer() < pivot.getCijfer()以及以下arr[i].getCijfer() < pivot.getCijfer()arr[j].getCijfer() > pivot.getCijfer()是问题的根源。 You need to extract these into a single function which returns an integer, implemented as follows: return Integer.compare( a.getCijfer(), b..getCijfer() ); 您需要将它们提取到一个返回整数的函数中,该函数实现如下: return Integer.compare( a.getCijfer(), b..getCijfer() ); .

But then you will notice that this is just a comparator function, so you can go ahead and modify it to work exactly as it worked when you were using Arrays.sort() with comparator. 但是然后您会注意到这只是一个比较器函数,因此您可以继续进行修改,使其完全与将Arrays.sort()与比较器一起使用时的工作方式一样。

This addresses your question. 这解决了您的问题。

However, be aware of the following: 但是,请注意以下几点:

  1. Your suspicion that Arrays.sort() will be slower than some quicksort is completely unfounded, and most likely false. 您完全怀疑Arrays.sort()速度会比某些quicksort慢,这完全没有根据,而且很可能是错误的。

  2. Your belief that you can do a home-brewed quicksort that will perform better than Arrays.sort() is most likely false. 您认为可以做一个比Arrays.sort()更好的自制快速排序的想法很可能是错误的。

  3. If you do not know how to get your home-brewed quicksort to sort the way you want it to, and you have to ask on stackoverflow, there is nothing wrong with that, but then obviously, sorting is a topic which is far more advanced than what your professor expects from you. 如果您不知道如何让自制的快速排序对您想要的方式进行排序,并且您必须询问stackoverflow,那么这没什么问题,但是显然,排序是一个更高级的主题比您的教授期望的要高。

You would need to put your second criterion anywhere you compare two Student instances, eg 您需要在比较两个Student实例的任何地方放置第二个条件,例如

if (arr[i].getCijfer() < pivot.getCijfer()
    || (arr[i].getCijfer() == pivot.getCijfer()
        && arr[i].getStudentNumber() < pivot.getStudentNumber()))

However, it is inconvenient to add multiple criteria here, so you would be better introducing a method in which the comparison is done: 但是,在此处添加多个条件很不方便,因此您最好引入一种进行比较的方法:

if (compare(arr[i], pivot) < 0)

and then pushing the comparison logic into that method, so that it returns some number depending upon whether arr[i] is less than, equal to, or greater than pivot . 然后推动比较逻辑到该方法中,以便它返回取决于是否一些数arr[i]比小于,等于,或大于pivot

Note that this is basically what Comparator provides: 请注意,这基本上是Comparator提供的:

class MyComparator implements Comparator<Student> {
  @Override int compare(Student a, Student b) {
    if (a.getCijfer() != b.getCijfer()) {
      return // Some comparison of a.getCijfer() and b.getCijfer()
    }
    // Somehow compare student number.
  }
}

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

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