快速排序
快速排序应该是排序算法中比较复杂的一种,也是性能相对来说做好的一种,平均时间复杂度为O(n logn)。快速排序实现起来比较困难的是枢纽(哨兵)的选择和数组的划分。快速排序同样使用了递归,划分的两部分数组分别调用自身。
数组划分主要是根据选取的枢纽,使得数组前半部分不大于枢纽值,后半部分不小于枢纽值。枢纽的选择是影响算法的效率的一个重要因数,简单版本中的快熟排序常将子数组最右端的数据项作为枢纽。但这也可能造成算法效率为O(n^2)的情况(逆序排序)。
高级快速排序中使用三数据取中(子数组中第一个,最后一个和中间一个数据的中值)选取枢纽,有效的解决了算法效率为O(n^2)的问题。由于比较实现相对比较困难,所以实例代码仅实现了简单版本的快速排序。
package algorithm;
import static java.lang.Math.random;
//实现快速排序
public class QuickSort {
public static void main(String args[]){
System.out.println("快速排序例子");
int maxSize = 16;
QuickSortArr arr = new QuickSortArr(maxSize);
for(int i = 0; i < maxSize; i++){
long value = (int)(random() * 99);
arr.insert(value);
}
arr.display();
arr.quickSort();
arr.display();
}
}
class QuickSortArr{
private long theArray[];
private int index;
public QuickSortArr(int size){
theArray = new long[size];
index = 0;
}
public void insert(long v){
theArray[index] = v;
index++;
}
public void display(){
System.out.print("the array: ");
for(int i = 0; i < theArray.length; i++){
System.out.print(theArray[i] + " ");
}
System.out.println();
}
public void quickSort(){
recQuickSort(0, index - 1);
}
private void recQuickSort(int left, int right) {
if(right - left <= 0){
return;
}
else {
long flag = theArray[right]; // 选最右的为flag
int ptt = partitionIt(left, right, flag);
recQuickSort(left, ptt - 1 );
recQuickSort(ptt + 1, right);
}
}
private int partitionIt(int left, int right, long flag) {
int leftPtr = left - 1; // 数组下标指针
int rightPtr = right;
while(true){
// 左移/右移,找到不满足条件的(先运算在比较)
while (theArray[++leftPtr] < flag);
while (theArray[--rightPtr] > flag && rightPtr > 0);
// 交换
if(leftPtr < rightPtr){
swap(leftPtr,rightPtr);
}
else
break;
}
swap(leftPtr, right); // 将flag值移动到leftPtr的位置,并返回下标
return leftPtr;
}
private void swap(int index1, int index2) {
long temp = theArray[index1];
theArray[index1] = theArray[index2];
theArray[index2] = temp;
}
}