我正在尝试使用升序和降序选项编写选择排序

Im trying to write a selection sort with ascending and descending options

我有一个选择排序方法可以按年份变量对我的对象进行排序。我让它按升序排序,但我似乎无法按降序排序。如果有人可以查看代码并可能为我指明正确的方向,那就太棒了

public static void sortYears(ArrayList<Movies3> list, int ad){
    int max, min,  i, j;
    Movies3 temp;

    if(ad == 1){
        for (i = 0; i < list.size() - 1; i++){
            max = i;

            for (j = i + 1; j < list.size(); j++){
                if (list.get(max).getYear() > list.get(j).getYear()){
                    max = j;
                }
            }

            temp = list.get(i);
            list.set(i, list.get(max));
            list.set(max, temp);
        }
    }else if(ad == 2){
        for (i = 0; i < list.size() - 1; i++){
            min = i;

            for (j = i + 1; j > list.size(); j++){
                if (list.get(min).getYear() < list.get(j).getYear()){
                    min = j;
                }
            }

            temp = list.get(i);
            list.set(i, list.get(min));
            list.set(min, temp);
        }
    }
}

for (j = i + 1; j > list.size(); j++){

谓词应该是 j < list.size(); 而不是 >,否则你的循环永远不会迭代,因为 i+1 总是 <=n,所以 j 总是 <=n

list.get(max).getYear() > list.get(j).getYear() 等直接比较替换为 Comparatorcomparator.compare(list.get(max).getYear(), list.get(j).getYear()) > 0

然后您可以轻松实现倒排 Comparator.reversed()

你的变量名和作用域真的很混乱,很多重复的代码。

for (j = i + 1; j > list.size(); j++) - 这行代码在大多数情况下永远不会执行。

这是对降序的修正:

// the same walk as for ASC but reversed comparison
for (int i = 0; i < list.size() - 1; i++) {
    candidateIndex = i;

    for (int j = i + 1; j < list.size(); j++) {
        if (list.get(candidateIndex).getYear() < list.get(j).getYear()) {
            candidateIndex = j;
        }
    }

    temp = list.get(i);
    list.set(i, list.get(candidateIndex));
    list.set(candidateIndex, temp);
}

你一定要看看Comparator:

A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort or Arrays.sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering. The ordering imposed by a comparator c on a set of elements S is said to be consistent with equals if and only if c.compare(e1, e2)==0 has the same boolean value as e1.equals(e2) for every e1 and e2 in S.

我将使用比较器写一个完整的例子:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class Main {
    /**
     * Defining comparator for ascending order by default
     */
    public static final Comparator<Movies3> COMPARATOR = (m1, m2) -> m1.getYear() - m2.getYear();

    public static void main(String[] args) {
        List<Movies3> movies = new ArrayList<>(
            Arrays.asList(new Movies3(1990), new Movies3(1995), new Movies3(2000)));

        sortYears(movies, true);
        System.out.println(movies);

        sortYears(movies, false);
        System.out.println(movies);
    }

    public static void sortYears(List<Movies3> list, boolean asc) {
        int candidateIndex; // index of candidate whatever min or max
        Movies3 temp;
        Comparator<Movies3> comparator;

        if (asc) {
            comparator = COMPARATOR;
        } else {
            comparator = COMPARATOR.reversed(); // switch to DESC order
        }

        for (int i = 0; i < list.size() - 1; i++) {
            candidateIndex = i;

            for (int j = i + 1; j < list.size(); j++) {
                if (comparator.compare(list.get(candidateIndex), list.get(j)) > 0) {
                    candidateIndex = j;
                }
            }

            temp = list.get(i);
            list.set(i, list.get(candidateIndex));
            list.set(candidateIndex, temp);
        }
    }
}

输出:

[year 1990, year 1995, year 2000]
[year 2000, year 1995, year 1990]

您还可以让您的 class 实现 Comparable 来为其定义自然顺序并使用它代替 Comparator

我建议你 class Movies3 必须实现接口 Comparable 并且 使用 java class 列表 创建自定义比较器。我认为这是更好更优雅的方式。

可能是这样的:

对于 Movie3 class

public class Movie3 implements Comparable<Movie3> {


private int year;
    private String author;
    private String genre;
    public Movie3(int year, String author, String genre) {
        super();
        this.year = year;
        this.author = author;
        this.genre = genre;
    }
    /**
     * @return the year
     */
    public int getYear() {
        return year;
    }
    /**
     * @param year the year to set
     */
    public void setYear(int year) {
        this.year = year;
    }
    /**
     * @return the author
     */
    public String getAuthor() {
        return author;
    }
    /**
     * @param author the author to set
     */
    public void setAuthor(String author) {
        this.author = author;
    }
    /**
     * @return the genre
     */
    public String getGenre() {
        return genre;
    }
    /**
     * @param genre the genre to set
     */
    public void setGenre(String genre) {
        this.genre = genre;
    }

    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("Year: "+this.getYear());
        sb.append("Author: "+this.getAuthor());
        sb.append("Genre: "+this.getGenre());
        return sb.toString();
    }
    public int compareTo(Movie3 m) {
        return Integer.compare(this.year, m.year);
    }

}

另一方面,自定义比较器很简单:

import java.util.Comparator;

public class MovieYearComparator implements Comparator<Movie3> {
    private boolean reverse;

    public MovieYearComparator(boolean reverse) {
        super();
        this.reverse = reverse;
    }

    @Override
    public int compare(Movie3 m1, Movie3 m2) 
    {
        if (reverse)
            return m1.getYear() < m2.getYear() ? 1 : m1.getYear() == m2.getYear() ? 0 : -1;
        else
            return m1.getYear() < m2.getYear() ? -1 : m1.getYear() == m2.getYear() ? 0 : 1;
    }
}

最后是测试:

import java.util.ArrayList;
import java.util.List;

import data.Movie3;
import data.MovieYearComparator;

public class test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Movie3> movies = new ArrayList<Movie3>();
        movies.add(new Movie3(1000,"sds","sdf"));
        movies.add(new Movie3(1001,"sds","sdf"));
        movies.add(new Movie3(2001,"sds","sdf"));
        movies.add(new Movie3(2444,"sds","sdf"));
        movies.add(new Movie3(1002,"sds","sdf"));
        movies.add(new Movie3(1003,"sds","sdf"));
        System.out.println(movies.toString());
        boolean reverse = true;
        movies.sort(new MovieYearComparator(!reverse));
        System.out.println(movies.toString());
        movies.sort(new MovieYearComparator(reverse));
        System.out.println(movies.toString());  

    }
}