在写快速排序前我们们可以写一下划分,划分的目的是数组基本有序,怎么使数组基本有序?这需要我们提前选一个值作为枢纽,作为划分数组的关键值,使大的元素和较小的元素分布在这个枢纽的两边,这就需要我们事先对数组里元素有一个大致上的了解。
//划分算法
public int parititon(int low, int pivot, int up) {//low为数组的第一个元素,piviot即我们的枢纽
int left = low-1;
int right = up;
while(true)
{
//一个数组从两边开始遍历元素,左边的元素遇到比枢纽大的时候(我们记为a)跳出,接着是右边,当右边遇到比枢纽小的时候(记为b)跳出
while(array[++left]<pivot);
//下面完整的程序中可看出,枢纽是取数组最右边的元素的,所以从右往左遍历时加了个界限的判定,即right>0,而从左往右则不需担心当然,之前已经说了枢纽是合理的(后面会具体说),枢纽值的不同会影响边界的判定
while(array[--right]>pivot&&right>0);
//当跳出循环后,先判断左边值是否大于等于右边,是表示遍历已结束可以跳出循环了否则,交换a,b
if(left>=right)
break;
else
swap(left,right);
}
return left;
}
基于划分算法,快速排序运用递归的方式不断将原来的数组进行分割,分割后的数组又调用划分算法,直至将数组全部拍完序。而枢纽每次都取数组的最右边的,在调用划分算法的末尾还需与右边较大的一个元素进行交换以得到更加合理的枢纽,其实这并不是一种取枢纽值的好方法,还有一种是三项取枢纽,在排序前对前中后先做一次比较,已得到更加合理的枢纽,大家可以试试只需在下面的代码做些小改动
package csnd;
public class QuickSort {
int array[];
int nElems;
public QuickSort() {
nElems=0;
}
public QuickSort(int max)
{
array = new int[max];
}
public void insert(int j)
{
array[nElems]=j;
nElems++;//注意,在这里当最后一个元素插入后,nElems值还会加一
}
public void display(){
for(int i=0;i<nElems;i++)
System.out.print(array[i]+" ");
System.out.println();
}
private void quickSort() {
// TODO Auto-generated method stub
requickSort(0, nElems-1);
}
public void requickSort(int low,int up) {
if(low>=up)
{
return;
}
else
{
int pivot = array[up];
int partition = parititon(low,pivot,up);
requickSort(low, partition-1);
requickSort(partition+1, up);
}
}
public int parititon(int low, int pivot, int up) {
int left = low-1;
int right = up;
while(true)
{
while(array[++left]<pivot);
while(array[--right]>pivot&&right>0);
if(left>=right)
break;
else
swap(left,right);
}
swap(left,up);//此时在与最右边的元素交换得到新数组
return left;
}
private void swap(int left, int right) {
int temp = array[left];
array[left]= array[right];
array[right]=temp;
}
public static void main(String[] args) {
QuickSort theArray = new QuickSort(10);
for(int i=0;i<10;i++)
{
int n=(int)(Math.random()*(10));
theArray.insert(n);
}
System.out.println("排序前的数组");
theArray.display();
System.out.println("排序后的数组");
theArray.quickSort();
theArray.display();
}
}
排序前的数组
3 9 1 5 2 6 2 0 0 0
排序后的数组
0 0 0 1 2 2 3 5 6 9