【问题标题】:Im trying to write a selection sort with ascending and descending options我正在尝试使用升序和降序选项编写选择排序
【发布时间】:2018-10-13 15:12:30
【问题描述】:

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

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

【问题讨论】:

  • AD变量是升序还是降序,1=升序,2=降序
  • 在第二个 if 语句中,您使用 for(j = i + 1; j &gt; list.size(); j++) 仅此行将评估为 false,因为在大多数情况下 j 很可能小于列表的大小,因此整个循环不会被执行。
  • 为什么不用比较器?

标签: java sorting selection


【解决方案1】:

我建议你的类Movies3必须实现接口Comparable使用java类List的排序方法创建一个自定义的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());  

    }
}

【讨论】:

  • 你可以使用Comparator.reverseOrder()而不是传递reverse标志
  • 谢谢鲁斯兰。我在 java 类 List 中寻找类似的东西。
【解决方案2】:

你的变量名和范围真的很混乱,很多重复的代码。

for (j = i + 1; j &gt; 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)以允许精确控制 在排序顺序上。比较器也可以用来控制顺序 某些数据结构(例如排序集或排序图),或 为没有 a 的对象集合提供排序 自然排序。 比较器 c 对一组元素 S 施加的排序称为 与 equals 一致当且仅当 c.compare(e1, e2)==0 有 对于 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】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-18
        • 2015-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多