排序-快速排序

来源:互联网 发布:图像尺寸测量软件 编辑:程序博客网 时间:2024/06/07 10:01

快速排序:

快速排序是最流行的排序算法,在大多数情况下,快速排序都是最快的,执行时间为O(N*logN)级。
快速排序算法本质上通过把一个数组划分为两个子数组,然后递归调用自身为每一个子数组进行快速排序实现的。
快速排序有三个基本的步骤:
1.把数组或者子数组分成左边(较小的关键字)的一组和右边(较大的关键字)的一组
2.调用自身对左边进行排序
3.再次调用自身对右边的一组进行排序。

经过一次划分之后,所有在左边子数组的数据项都小于在右边子数组的数据项,只要对左边子数组和右边子数组分别进行排序,整个数组就是有序的了,也通过递归调用排序算法自身就可以。

传递给recQuickSort()方法的参数决定了要排序数组的左右两端位置,这个方法首先检查数组是否只包含一个数据项,如果数组只包含一个数据项,那么就定义数组已经有序,方法立即返回,这就是递归的基值条件(递归的出口)。

如果数组包含两个或者更多的数据项,算法就调用partitionIt()方法对数组进行划分。方法返回分隔边界的下标数值(partition),它指向右边(较大关键字)z子数组最左端的数据项。

这里写图片描述

对数组进行划分之后,recQuickSort()递归的调用自身,数组左边的部分调用一次,对从left到partition-1位置上的数据项进行排序,数组右边的部分也调用一次,对从partition到right位置上的数据项进行排序。注意这两个递归都不包含数组下标为partition的数据项,为什么呢?原因在于轴值(枢纽)的选择

选择轴值:partitionIt()方法应该使用什么样的轴值呢,下面是一些相关的想法:
–应该选择具体的一个数据项的关键字的值作为轴值,这个数据项称为pivot(轴值)
–可以选择任意一个数据项作为轴值。为了简便,我们总是假设总是选择待划分的子数组的最右端的数据项作为轴值
—划分完成之后,如果轴值插到左右子数组之间的分界处,那么轴值就落在排序之后的最终位置上。

这里写图片描述

为了实现把把轴值放入正确位置的操作,只要交换轴值和右边子数组的最左端的数据项就可以了。这个交换操作把轴值放在了正确的位置上,也就是左右子数组之间

完整代码:

public class QuickSortTest{    private  int[]  array;    private  int  number;    public  QuickSortTest(int  max)    {        array = new int[max];        number = 0;    }    public  void insert(int  value)    {        array[number] = value;        number++;    }    public  void display()    {        for (int i = 0; i < number; i++)        {            System.out.print(array[i]+" ");            System.out.print(" ");        }    }    public  void quickSort()    {        recQuickSort(0, number-1);    }    //递归调用的方法    public  void recQuickSort(int  left,int  right)    {        if(right -left <= 0)            return;        else        {            int pivot =array[right]; //选定最右边元素作为轴值            int partition = partitionIt(left, right, pivot);            recQuickSort(left, partition-1);  //递归,将左边的元素排序            recQuickSort(partition+1, right);  //递归,将右边的元素排序        }    }    //分隔数组的方法    public  int partitionIt(int  left,int right,int  pivot)    {        int leftPointer= left-1;   //左指针        int rightPointer= right;    //右指针        while(true)        {            //左指针移动,移动到下一个元素比轴值小  ,不用交换            //因为我们的目的是找到所有比轴值小的元素放在轴值左边,所有比轴值大的元素放在轴值右边            while(array[++leftPointer] < pivot);             //右指针移动,移动到下一个元素如果比轴值大,不用交换            while(rightPointer>0   &&  array[rightPointer--]>pivot);            //z左指针大于等于右指针,也就是两个指针相遇了,就停下来。            if(leftPointer >= rightPointer)            break;            else            swap(leftPointer,rightPointer);        }        swap(leftPointer,right); //将轴值与左指针交换        return leftPointer;  //返回轴值的位置    }    //用于交换两个元素的方法    public   void  swap(int  index1,int index2)    {        int  temp =array[index1];        array[index1] = array[index2];        array[index2] = temp;    }    public static void main(String[] args)    {        int  max=16;        QuickSortTest  array=new QuickSortTest(max);        array.insert(76);        array.insert(78);        array.insert(78);        array.insert(7);        array.insert(8);        array.insert(478);        array.insert(728);        array.quickSort();        array.display();    }}
0 0