/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package technology.tabula;
import java.util.Comparator;
import java.util.List;
import java.util.Stack;
/**
* see http://de.wikipedia.org/wiki/Quicksort.
*
* @author UWe Pachler
*/
public class QuickSort
{
private QuickSort()
{
}
private static final Comparator<? extends Comparable> objComp = new Comparator<Comparable>()
{
public int compare(Comparable object1, Comparable object2)
{
return object1.compareTo(object2);
}
};
/**
* Sorts the given list using the given comparator.
*/
public static <T> void sort(List<T> list, Comparator<T> cmp)
{
quicksort(list, cmp);
}
/**
* Sorts the given list using compareTo as comparator.
*/
public static <T extends Comparable> void sort(List<T> list)
{
sort(list, (Comparator<T>) objComp);
}
private static <T> void quicksort(List<T> list, Comparator<T> cmp)
{
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
stack.push(list.size());
while (!stack.isEmpty()) {
int right = stack.pop();
int left = stack.pop();
if (right - left < 2) continue;
int p = left + ((right-left)/2);
p = partition(list, cmp, p, left, right);
stack.push(p+1);
stack.push(right);
stack.push(left);
stack.push(p);
}
}
private static <T> int partition(List<T> list, Comparator<T> cmp, int p, int start, int end) {
int l = start;
int h = end - 2;
T piv = list.get(p);
swap(list,p,end-1);
while (l < h) {
if (cmp.compare(list.get(l), piv) <= 0) {
l++;
} else if (cmp.compare(piv, list.get(h)) <= 0) {
h--;
} else {
swap(list,l,h);
}
}
int idx = h;
if (cmp.compare(list.get(h), piv) < 0) idx++;
swap(list,end-1,idx);
return idx;
}
private static <T> void swap(List<T> list, int i, int j)
{
T tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);
}
}