Quick Sort-快速排序

此贴由戴维营教育学员翻译,大茶园丁整理,特意为戴维营教育零基础学员课外学习之用.

快速排序像归并排序一样是一个分而治之的算法,但它不想归并排序那样,它不需要额外的空间,在待排序的集合内就地排序。

这个分割步骤就是选择一个基准点把数组分割,小于或等于基准点的元素全排到左边去,大于或等于基准点的元素全部排到基准点右边去。再依次对左右两边的元素递归地进行快速排序。

算法

该算法的关键在于分区.

  • 从数列中挑出一个元素,称为 "基准"(pivot),
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

基准选择与分区:

快速排序图示:

特性

  • 最佳性能:当分区产生两个区域的大小是n/2时(n是列表中的元素的总数),时间复杂度为O(nlgn).
  • 最差性能:当分区产生一个区域的大小是n - 1时(n是列表中的元素的总数),另一个区域大小为1,时间复杂度为O(n2).
  • 平均情况:时间复杂度O(n(lgn))
  • 在最坏的情况下,使用O(lg(n))额外的空间, 这是一个不稳定的算法。

快速排序-C语言代码

#include <stdio.h>/* Logic:This is divide and conquer algorithm like Merge Sort.Unlike Merge Sort this does not require extra space.So it sorts in place.Here dividing step is chose a pivot and parition the array such that all elements less than or equal to pivot are to the left of it andd all the elements which are greater than or equal to the pivot are to the right of it.Recursivley sort the left and right parts.*/void QuickSort(int *array, int from, int to){        if(from>=to)return;        int pivot = array[from]; /*Pivot I am chosing is the starting element */        /*Here i and j are such that in the array all elemnts a[from+1...i] are less than pivot, all elements a[i+1...j] are greater than pivot and the elements a[j+1...to] are which we have not seen which is like shown below.          ________________________i_________________j___________          |pivot|....<=pivot......|....>=pivot......|.........|          If the new element we encounter than >=pivot the above variant is still satisfied.          If it is less than pivot we swap a[j] with a[i+1].         */        int i = from, j, temp;        for(j = from + 1;j <= to;j++)        {                if(array[j] < pivot)                 {                        i = i + 1;                        temp = array[i];                        array[i] = array[j];                        array[j] = temp;                }        }        /* Finally The picture is like shown below          _______________________i____________________          |pivot|....<=pivot......|....>=pivot......|        */        temp = array[i];        array[i] = array[from];        array[from] = temp;        /* So we the array is now           ____________________i______________________          |...<=pivot......|pivot|....>=pivot......|        */        /*Recursively sort the two sub arrays */        QuickSort(array,from,i-1);        QuickSort(array,i+1,to);}int main(){        int number_of_elements;        scanf("%d",&number_of_elements);        int array[number_of_elements];         int iter;        for(iter = 0;iter < number_of_elements;iter++)        {                scanf("%d",&array[iter]);        }        /* Calling this functions sorts the array */        QuickSort(array,0,number_of_elements-1);         for(iter = 0;iter < number_of_elements;iter++)        {                printf("%d ",array[iter]);        }        printf("\n");        return 0;}