简体   繁体   中英

java - Quick Sort - ArrayList - is not working

I am having trouble finding a bug in this sorting algorithm. When I pass an array to the sort method, say 5,6,4,7,1, I get the same array as result. I've been going through code but I cannot find where it is going wrong. Disregard SortThread task, it's an argument that will update the progress bar, but I am not using it right now.

class QuickSort extends Sort {

@Override
ArrayList<Integer> sort(ArrayList<Integer> array, SortThread task) {

    if (array.size() <= 1) {
        return array;
    }

    int middle = (int) Math.ceil((double) array.size() / 2);
    int pivot = array.get(middle);

    ArrayList<Integer> less = new ArrayList<>();
    ArrayList<Integer> greater = new ArrayList<>();

    for (int i = 0; i < array.size(); i++) {
        if (array.get(i) <= pivot) {
            if (i == middle) {
                continue;
            }
            less.add(array.get(i));
        } else {
            greater.add(array.get(i));
        }
    }

    return concatenate(sort(less, task), pivot, sort(greater, task));
}

private ArrayList<Integer> concatenate(ArrayList<Integer> less, int pivot, ArrayList<Integer> greater) {

    ArrayList<Integer> list = new ArrayList<>();

    for (int i = 0; i < less.size(); i++) {
        list.add(less.get(i));
    }

    list.add(pivot);

    for (int i = 0; i < greater.size(); i++) {
        list.add(greater.get(i));
    }

    return list;
}

}

The others have it right that you are probably printing the original as your code works fine.

You could try this instead, which will sort it in-situ, thus having less unexpected behaviour and being slightly more efficient. All I have done is made concatenate take a new parameter which is where it should put its results.

BTW: I would suggest you pull out the if (i == middle) { continue; } if (i == middle) { continue; } to before you compare, this would also be slightly more efficient.

static class QuickSort {

  public static ArrayList<Integer> sort(ArrayList<Integer> array) {

    if (array.size() <= 1) {
      return array;
    }

    int middle = (int) Math.ceil((double) array.size() / 2);
    int pivot = array.get(middle);

    ArrayList<Integer> less = new ArrayList<>();
    ArrayList<Integer> greater = new ArrayList<>();

    for (int i = 0; i < array.size(); i++) {
      if (array.get(i) <= pivot) {
        if (i == middle) {
          continue;
        }
        less.add(array.get(i));
      } else {
        greater.add(array.get(i));
      }
    }

    return concatenate(sort(less), pivot, sort(greater), array);
  }

  private static ArrayList<Integer> concatenate(ArrayList<Integer> less, int pivot, ArrayList<Integer> greater, ArrayList<Integer> list) {

    list.clear();

    for (int i = 0; i < less.size(); i++) {
      list.add(less.get(i));
    }

    list.add(pivot);

    for (int i = 0; i < greater.size(); i++) {
      list.add(greater.get(i));
    }

    return list;
  }
} 

you could further improve concatenate to:

    list.clear();
    list.addAll(less);
    list.add(pivot);
    list.addAll(greater);

You are not doing any actual sorting. You are just putting everything into smaller lists, then putting them back into a larger list. You need some comparisons in there.

Look at your concatenate method. Your are just putting the less list back into the less list. You need to compare the value to the pivot to determine where that value should go.

EDIT: My initial thought was wrong. I tested your code and it worked.

I'm guessing you are printing out the the array you passed in? Note that the actual array you pass into your sort function is not sorted. Only the one returned.

array.get(i)返回一个Integer,您需要提取包装的int,否则将比较指针。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM