基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序整个排序过程可以递归进行,以此达到整个数据变成有序序列。快速排序采用了分治法来解决问题。

过程:

1.从序列中挑出一个元素,称为基准.一般是第一个元素

2.重新排列数列,进行比较,比基准元素小的元素放在基准前面,比基准大的元素放在基准的后面,一次排序完成后,基准就处于数列的中间位置,也是分区操作.

3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

4、直到序列的大小是0或1,也就是所有元素都已经被排序好了,递归结束。

时间和空间复杂度:

1.快速排序最坏的情况就是初始序列有序或者基本有序时,蜕化为冒泡排序,时间复杂度为O(n^2),空间复杂度为O(n).

2.快速排序最好的情况就是每次排序所选的基准都能进行二分,时间复杂度为O(nlogn),空间复杂度为O(nlogn)

3.快速排序的平均时间复杂度为o(nlogn),空间复杂度为(O(logn))

稳定性:是一种不稳定的排序算法

图示第一趟过程:(图从别人博客中复制过来的)

快速排序(java)

public class QuickSort {
    public static void main(String[] args) {
        int arr[] = {5, 7, 2, 4, 1, 8, 3};
        sort(arr, 0, arr.length - 1);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }

    }
    //固定的切分方式
public static int  partion(int arr[],int left,int right)
{
    int key=arr[left];
    while(left<right)
    {
     while(arr[right]>=key&&left<right)//从后半部分向前扫描
     {
         right--;
     }
     arr[left]=arr[right];
     while(arr[left]<key&&left<right)//从前半部分向后扫描
     {
         left++;
     }
     arr[right]=arr[left];
    }
    arr[right]=key;
    return right;
}
//递归
public static void sort(int arr[],int left,int right)
{
    if(left>=right)
    {
        return ;
    }
    int index=partion(arr,left,right);

    sort(arr,left,index-1);
    sort(arr,index+1,right);
}
}

优点:

对于大量不重复的数据,很容易放在对应的位置.

缺点:

1.如果数据时有序的,那么快速排序过程中对序列的划分就十分不均匀,将序列分为1和n-1的大小(通常理想的状态是二分)

2.不稳定的排序,当重复数据较多的时候效率比较低

3.对于小数组进行排序时,也是进行几次才能将数据放到正确的位置

相关文章: