快速排序分析总结

快速排序算法分析


分析与步骤

快速排序算法和归并排序类似,都是属于分治算法。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

步骤为:

从数列中挑出一个元素,称为 “基准”(pivot),
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
虽然快速排序是分治算法,但其中主要的操作是分区操作,这个操作的复杂性应该是线性的。划分的实现由很多种,朴素的实现是选取第一个元素和最后一个元素作为基准作为划分。算法导论一书给出的partition 函数是取最后一个元素作为基准,然后通过一遍循环交换元素。代码虽然简洁,但是初看起来不太易懂,建议在纸上模拟下过程。此种方法相对来说交换元素的次数也比较多,后面会给出一种优化的操作。


C语言实现

/* 快速排序朴素的实现 */
#include<stdio.h>

void swap(int* a, int* b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

/*取最后一个作为基准 */
int partition (int arr[], int l, int h)
{
    int x = arr[h];   
    int i = (l - 1);  // 较小元素的下标
    for (int j = l; j <= h- 1; j++)
    {
        if (arr[j] <= x)
        {
            i++;    //增加较小元素的下标
            swap(&arr[i], &arr[j]); 
        }
    }
    swap(&arr[i + 1], &arr[h]);  
    return (i + 1);//返回基准元素的最终位置
}

/* arr[] --> 待排序数组, l  --> 开始位置, h  -->结束位置 */
void quickSort(int arr[], int l, int h)
{
    if (l < h)
    {
        int p = partition(arr, l, h); /* p为划分的中间位置 */
        quickSort(arr, l, p - 1);
        quickSort(arr, p + 1, h);
    }
}

/* 打印数组 */
void printArray(int arr[], int size)
{
    int i;
    for (i=0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

// 测试
int main()
{
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    quickSort(arr, 0, n-1);
    printf("Sorted array: \n");
    printArray(arr, n);
    return 0;
}

输出:

Sorted array:
1 5 7 8 9 10

时间复杂度可以算出为时间的复杂度可以表示为:T(n) = T(k) + T(n-k-1) + P(n)

虽然快速排序的最坏情况下复杂度为O(N^2),这比很多其他的排序算法,如归并排序和堆排序,在实践中更快.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值