快速排序的随笔

先上代码吧,以下是结合网上代码修改的一个快速排序的demo.
先来搞个"排序"的虚基类:

public abstract class AbstractSorter<E extends Comparable<E>> {

public abstract void sort(E[] array,int low ,int high);

public final void sort(E[] array)
{
sort(array,0,array.length-1);
}
/**
* 互换函数*/
public final void swap(E[] array, int i, int j){
E tempE = array[i];
array[i] = array[j];
array[j] = tempE;
}
}

再来一个快速排序的实现继承:

public class QuickSorter<E extends Comparable<E>> extends AbstractSorter<E> {

public QuickSorter() {
// TODO Auto-generated constructor stub
}

@Override
public void sort(E[] array, int low, int high) {
if(low < high){
int pivot = partition(array, low, high);
this.sort(array, low, pivot-1);
this.sort(array, pivot+1, high);
}

}

private int partition(E[] array, int low, int high) {
E pivotContent = array[high];
int itrace = low;
for(int j=low;j<high;++j){
if(array[j].compareTo(pivotContent)<0){
swap(array, itrace++, j);
}
}
swap(array, itrace, high);
return itrace;
}
}

好吧,其实我之前还不大清楚什么是快速排序的,现在研究了代码,就比较清晰了.
快速排序就是在队列任选一个元素为支点,把支点放入一个位置,这个位置的左侧全是比它小的元素,而右侧全是比它大的元素,即就支点和左右两段来说,队列是已排序的.然后再对左右两段递归进行快速排序,最后就得到了有序队列.
快速排序的关键点就是在于把所选取的支点元素正确放入它本该处于的位置(亦即最后有序时的正确位置).在上述实现中,选取的就是该段数组最大索引的元素为支点.然后从左到右遍历数组,发现大于支点元素的就跳过,发现小于支点元素的就把该元素和"尽可能左方"的untouched的元素对换.所谓untouched,要么就是之前被跳过的元素,即比支点元素大的元素,要么就是被置换过的元素,而必然地,也是比支点元素大的元素.这一切由itrace变量即一个表示置换进度的变量所控制,每发生一次置换,自增一次. 当所有元素已经check过了之后,再把itrace当下位置的元素与最大索引的元素置换.返回itrace,即支点元素的索引,也是最后有序的索引,从而完成了一次排序.接下来就是分别对itrace左右两段各执行上述排序过程~

解释:如上所述,itrace变量是一个表示置换进度的变量,每发生一次置换,自增一次. 实际上,itrace的意义在于,它左方的元素,都是比支点元素小的,因此,当遍历完一次数组时,所有的比支点小的元素已经云集到itrace指示的索引左方;最后,把itrace索引所在的当前元素(肯定是某个比支点大的元素)与支点交换,于是,支点元素就得到了妥善安置,所有左方元素都比它小,所有右方元素都比它大.

最后,提一提快速排序的时间复杂度为O(nlogn),最差情况下(本例选取的支点为最后一个元素则逆序时为最差(未验证))为O(n^2).
测试用main函数如下:

/**
* @param args
*/
public static void main(String[] args) {
Integer[] array = {12,15,7,2,8,10};
AbstractSorter<Integer> sorter = new QuickSorter<Integer>();
sorter.sort(array);

for(int i = 0;i<array.length;i++){
System.out.print(array[i].intValue()+" ");
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值