我试图用升序和降序选项编写选择排序

时间:2018-05-03 10:27:12

标签: java sorting selection

我有一个选择排序方法来按年变量对对象进行排序。我让它按升序排序,我似乎无法使降序工作。如果有人能够查看代码并且可能指向正确的方向,那将是非常棒的

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

4 个答案:

答案 0 :(得分:2)

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

谓词应为j < list.size();而不是>,否则您的循环永远不会以i+1始终<=n进行迭代,因此j始终为{{1} }}

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

您的变量名称和范围确实令人困惑,许多重复的代码。

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

  

比较函数,对某些函数施加总排序   对象的集合。可以将比较器传递给排序方法   (例如Collections.sort或Arrays.sort)允许精确控制   超过排序顺序。比较器也可用于控制订单   某些数据结构(如排序集或排序映射)或   为没有的对象集合提供排序   自然排序。   比较器c对一组元素S施加的排序被称为   当且仅当c.compare(e1,e2)== 0具有时,才与equals一致   对于S中的每个e1和e2,与e1.equals(e2)相同的布尔值。

我将使用比较器编写完整的示例:

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]

您也可以让您的班级实施Comparable来为其定义自然排序,并使用它代替Comparator

答案 3 :(得分:0)

我建议你的班级 Movies3必须实现可比较的界面使用java类列表的排序方法创建自定义Comparator 。我认为这是更好,更优雅的方式。

可能是这样的:

对于 Movie3类

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

    }
}