对 2D ArrayList 进行冒泡排序

Posted

技术标签:

【中文标题】对 2D ArrayList 进行冒泡排序【英文标题】:Bubble sorting a 2D ArrayList 【发布时间】:2019-06-14 10:57:15 【问题描述】:

我正在尝试对内部列表中有 7 列的 2d ArrayList 进行冒泡排序。第三列是价格。我正在尝试比较行的价格列,并将价格较高的行与价格较低的行交换。这意味着最终 ArrayList 应该有按价格升序排列的行。

但是每次交换行时,较大行中的所有元素都会更改为较小行中的相同元素。下面是代码。

boolean found = true;
do
    found = false;
    for(int i = 0; i <= rc; i++) 
        if(i + 1 <= rc) 
            if(Integer.parseInt(list.get(i).get(3)) > Integer.parseInt(list.get(i + 1).get(3))) 
                ArrayList<String> greater = list.get(i);
                ArrayList<String> smaller = list.get(i + 1);
                for(int k = 0; k <= 7; k++) 
                    list.get(i).set(k, smaller.get(k));
                    list.get(i + 1).set(k, greater.get(k));
                   
                found = true;
            
        
    
 while(found == true);

原始数组列表:

[[1, sagarmatha, 5000, 7000, Two-Star, Two-Person-Room, 2, Resturant],
 [2, barahi, 4000, 4000, Three-Star, One-Person-Room, 1, Free-WIFI]]

排序后:

[[2, barahi, 4000, 4000, Three-Star, One-Person-Room, 1, Free-WIFI],
 [2, barahi, 4000, 4000, Three-Star, One-Person-Room, 1, Free-WIFI]]

【问题讨论】:

尝试只移动引用而不是复制数组的内容。如果没有中间缓冲区,你就会遇到这个问题。 【参考方案1】:

在您的情况下,您没有创建新列表。相反,您正在使用列表的引用。因此:

greater = list.get(i);  //here greater _references_ the i'th element
                        //[1, sagarmatha, 5000, 7000, Two-Star, Two-Person-Room, 2, Resturant]

smaller = list.get(i+1); //here greater _references_ the i+1'th element
                         //[2, barahi, 4000, 4000, Three-Star, One-Person-Room, 1, Free-WIFI]

 for(int k =0; k<=7; k++)
     list.get(i).set(k, smaller.get(k));
     list.get(i+1).set(k, greater.get(k));
    

让我们看看循环中发生了什么:

when k = 0: 
before assignment: list.get(i).get(0) = greater.get(0) = 1
                   list.get(i+1).get(0) = smaller.get(0) = 2

after assignment: list.get(i).get(0) = greater.get(0) = 2 which is the value of "smaller"

当您更改第一个列表的元素时,greater 的值也会更改,因为greaterlist.get(0) 基本上是同一个对象,而不是彼此的副本。您需要创建另一个数组,然后复制这些值。或者您可以随时使用临时变量直接交换数组列表,例如::

private void swap (ArrayList list, int index1, int index2) 
    object temp = ArrayList[index1];
    ArrayList[index1] = ArrayList[index2];
    ArrayList[index2] = temp;

【讨论】:

【参考方案2】:

让我们从在ArrayList 中交换两个元素的最有效方式开始:

public void <T> swap(ArrayList<T> list, int i, int j)

    T tmp = list.get(i);
    list.set(i, list.get(j));
    list.set(j, tmp);

这很有效,因为它不会以任何方式接触元素,只是移动引用。它使用set,因此列表中的任何元素都不会被移动,也不会被重新分配。

现在让我们看看你的交换是如何写的:

ArrayList<String> greater = list.get(i);
ArrayList<String> smaller = list.get(i + 1);
for(int k = 0; k <= 7; k++) 
    list.get(i).set(k, smaller.get(k));
    list.get(i + 1).set(k, greater.get(k));

for 循环试图将一个列表中的数据复制到另一个列表中,这在开始时并不是最优的。真正的问题是您没有使用临时变量来保存交换(请注意我在上面的函数中是如何做到的)。让我们看看在交换期间数据的kth 元素发生了什么:

    smaller.get(k)开头->“A”和greater.get(k)->“B” 在list.get(i).set(k, smaller.get(k)); 之后,你会得到smaller.get(k) -> "A" 和greater.get(k) -> "A",因为list.get(i) == greaterlist.get(i + 1).set(k, greater.get(k)); 只是将“A”重新分配给 smaller,因为第一行破坏了最初在 greater 中的任何内容。

要解决此问题,您需要先将 greater.get(k) 的原始值存储到临时变量中:

ArrayList<String> greater = list.get(i);
ArrayList<String> smaller = list.get(i + 1);
for(int k = 0; k <= 7; k++) 
    String temp = greater.get(k);
    greater.set(k, smaller.get(k));
    smaller.set(k, temp);

【讨论】:

以上是关于对 2D ArrayList 进行冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章

Java中的ArrayList怎么进行冒泡排序

冒泡实现ArrayList里面的对象排序

java对Arraylist冒泡排序,怎么合理调用一个函数实现?

用Java中ArrayList类实现一个冒泡排序

算法设计与分析基础5冒泡排序与选择排序

ArrayList 冒泡排序 帮忙看下这个,里面用set()如何排序啊?