【问题标题】:Selection sorting an instance of an object of type ArrayList of objects giving weird results选择对类型为 ArrayList 的对象的实例进行排序,给出奇怪的结果
【发布时间】:2018-10-11 02:24:23
【问题描述】:

我有一个 CarLot 类、一个 Car 类和一个 CarLotApp 类来为其设置 GUI。 CarLot 是 Car 对象的 ArrayList。我在 CarLot 中有方法,可以根据 Car 中的实例变量(品牌、型号、mpg 等)对 CarLot 进行选择排序

例如:

public ArrayList<Car> getSortedDescMPG() {
    ArrayList<Car> lotSortedByMPG = new ArrayList<Car>(myCars);
    Car car; 
        for (Car c : lotSortedByMPG) {
            double currentMax = c.getMPG();
            car = c;
            int currentMaxIndex = lotSortedByMPG.indexOf(c);

            for (Car c2 : lotSortedByMPG) {
                if (currentMax < c2.getMPG()) {
                    currentMax = c2.getMPG();
                    car = c2;
                    currentMaxIndex = lotSortedByMPG.indexOf(c2);
                }
            }
            if (currentMaxIndex != lotSortedByMPG.indexOf(c)) {
                lotSortedByMPG.set(currentMaxIndex, c);
                lotSortedByMPG.set(lotSortedByMPG.indexOf(c), car);
            }
        }
        return lotSortedByMPG;
}

我正在尝试将排序列表放入 CarLotApp 中的 TextArea。在 CarLotApp 中,我还有三个按钮,一个用于添加汽车,一个用于按 asc 排序,一个用于按 desc 排序,还有一个用于选择要排序的实例变量的组合框。

class SortDesc extends WidgetViewerActionEvent {

    @Override
    public void actionPerformed(ActionEvent event) {            

        txtrSortedCarLot.setText("");
        if (cmbSortOptions.getSelectedIndex() == 0) 
            txtrSortedCarLot.setText(myCarLot.toString());
        else if (cmbSortOptions.getSelectedIndex() == 1)
            txtrSortedCarLot.setText(CarLot.toString(myCarLot.getSortedDescMPG()));
        else if (cmbSortOptions.getSelectedIndex() == 2)
            etc...
    }
}

主要问题是从我的排序方法中吐出的 ArrayLists 是乱序的。我寻找了类似的帖子,但它们都链接到一个专注于使用比较器进行排序的帖子。我想在不使用比较器的情况下做到这一点。所以我真的不知道要搜索什么,因为我可以告诉我的排序方法应该有效。所以我不知道我做错了什么。

【问题讨论】:

  • if (currentMax &lt; c2.getSomeMPG()) { currentMax = c2.getMPG():看起来您正在测试是否应该将一件事变成新的currentMax,然后将另一件事完全变成新的currentMax。
  • 它正在更新 currentMax。如果我们认为当前的最大值比其他值小,则它不可能是实际的最大值,因此我们将其更新为我们刚刚找到的新 currentMax。
  • 您刚刚描述了它应该的工作方式。我是说这不是它正在做的事情。您与c2.getSomeMPG() 相比,所以c2.getSomeMPG() 应该是新的currentMax,是吗?但是您随后将currentMax 设置为c2.getMPG(),而不是c2.getSomeMPG()。那只是一个错字吗?还是c2.getSomeMPG() 和c2.getMPG() 神奇地是同一件事?
  • @KevinAnderson 是的,这是一个错字,我现在改正了

标签: java sorting arraylist selection-sort


【解决方案1】:

当您进行选择排序时,数组或列表的开头正在排序,您不应该在那里寻找最大值。您宁愿在列表的 余数 中找到最大值,该值仍未排序。相反,您的代码会反复查找具有最大 MPG 的同一辆车。

这是一个有效的选择排序:

public static ArrayList<Car> getSortedDescMPG() {
    ArrayList<Car> lotSortedByMPG = new ArrayList<>(myCars);
    for (int i = 0; i < lotSortedByMPG.size(); i++) {
        // At the beginning of each iteration, cars 0 through (i-1) are sorted

        // Find the max-MPG car with index in the range (i, size-1) inclusive
        Car carI = lotSortedByMPG.get(i);
        int maxIndex = i;
        Car maxCar = carI;
        int maxMPG = carI.getMPG();
        for (int j = i + 1; j < lotSortedByMPG.size(); j++) {
            Car curCar = lotSortedByMPG.get(j);
            int curMPG = curCar.getMPG();
            if (curMPG > maxMPG) {
                maxIndex = j;
                maxCar = curCar;
                maxMPG = curMPG;
            }
        }

        // Now swap the max-MPG car (at index maxIndex) with car i (at index i)
        lotSortedByMPG.set(i, maxCar);
        lotSortedByMPG.set(maxIndex, carI);
    }
    return lotSortedByMPG;
}

【讨论】:

  • 第一个 for 循环不是负责两次找到同一辆车吗?
  • 哦,我明白了。我不应该为每个循环使用一个
猜你喜欢
  • 2017-10-21
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 2013-08-20
  • 2022-01-18
  • 2013-11-06
  • 1970-01-01
相关资源
最近更新 更多