当listsize为< = 10时,尝试实现快速排序并使用插入排序

时间:2014-07-06 02:31:29

标签: java sorting insertion-sort

import java.util.Comparator;


public class SortedList implements Container{
private int size;
private int front = 0;
private int rear = 0;
private WorkOrder[] buffer;
Comparator comparator;

public SortedList(){
    buffer = new WorkOrder[10];
}
/**
 * The comparator that the container will use to arrange the container
 * 
 * @param comp
 */
public void setComparator(Comparator comp){
    if (comp == null){
        throw new IllegalArgumentException();
    }
    comparator = comp;
}

/**
 * Add a workorder to the container
 */
public void add(WorkOrder wo){
    if(wo == null){
        throw new IllegalArgumentException();
    }
    if (size == capacity()){
        WorkOrder[] regrowArray = new WorkOrder[2*capacity()];
        for (int i = 0; i<size;i++){
            regrowArray[i] = buffer[i];
        }
        buffer = regrowArray;
        rear = size;
    }

    buffer[rear] = wo;
    rear++;
    size++;
}

/**
 * Gets a workorder (removes it also) from the container
 */
public WorkOrder getNext(){
    if (isEmpty()){
        return null;
    }
    WorkOrder itemRemoved = buffer[front];
    buffer[front] = null;
    front++;
    size--;

    return itemRemoved;
}

/**
 * Arranges the workorders in the required order
 * Uses the comparator if necessary
 * Some data structures may not need this method (like Queue)
 * Just make it a no-op for those structures.
 */
public void arrange(){
    if (buffer == null || size == 0){
        return;
    }
    partition(0,size-1);
    //sort(0,size-1);
}

private void partition(int left, int right){
    int pivotIndex = (right + left) / 2;
    int i = left;
    int j = right;

    if ((right-left) <= 10){
        insertionSort(left,right);
        return;
    }
    while (i <= j){
        while (comparator.compare(buffer[i],buffer[pivotIndex]) < 0){
            i++;
        }
        while (comparator.compare(buffer[j],buffer[pivotIndex]) > 0){
            j--;
        }
        if (i <= j){
            swap(i,j);
            i++;
            j--;
        }
    }
    if (left < j){
        partition(left,j);
    }
    if (i<right){
        partition(i, right);
    }
}

private void insertionSort(int left, int right){
    for (int i = 1; i < right; i++){
        WorkOrder val = buffer[i];
        int j = i - 1;
        while (j>=0 && comparator.compare(buffer[j], val) > 0){
            buffer[j+1] = buffer[j];
            j = j - 1;
        }
        buffer[j+1] = val;
    }
}

private void swap(int x, int y){
    WorkOrder temp = buffer[x];
    buffer[x] = buffer[y];
    buffer[y] = temp;
}
}

我看到的输出是: 0123567894

传入的比较器取决于在其上运行的junits,这就是我使用比较器的原因。比较一切。我几乎肯定排序算法是正确的,我可能错误地操纵了后备阵列。

1 个答案:

答案 0 :(得分:0)

问题似乎是insertion sort部分:

for (int i = 1; i < right; i++){ //going from 1 to one previous to the last (right - 1)
    WorkOrder val = buffer[i];
    int j = i - 1;
    while (j>=0 && comparator.compare(buffer[j], val) > 0){
        buffer[j+1] = buffer[j];
        j = j - 1;
    }
    buffer[j+1] = val;
}

你需要考虑它需要循环到最后一个,因为你知道right变量是该分区的最后一个索引。

for (int i = 1; i <= right; i++) //replace < for <=

因为当数组的10个或更少的元素时,right是最后一个索引(并且需要考虑它)。

edit:

我看到的唯一的东西(在quick sort代码中)是这一部分:

if (left < j){ 
    partition(left,j); //trying to partition from left to j (since 'j' and 'i' may overlap)
}

应该是

if (left < (i - 1)){ 
    partition(left,i - 1); //so the partition doesnt overlap with the 'i' to 'right' partition by an element (since i and j may overlap at the end).
}

这样可以确保您始终将分区分成两半。