算法导论值快速排序

12 篇文章 0 订阅
8 篇文章 0 订阅

    今天和大家一起讨论快速排序,对于包含n个数的输入数组来说,快速排序是一种最坏情况时间复杂度为o(n * n)的排序算法。虽然最坏情况时间复杂度很差,但是快速排序通常是实际排序应用中最好的选择,因为它的平均性能非常好;它的期望时间复杂度为o(n lgn),而且o(n lgn)中隐含的常数因子非常小。另外,它还能进行原址排序,甚至在虚存环境中也能很好的工作。

     快速排序的描述:

            与归并排序一样,快速排序也使用了分治思想,下面是对一个典型的子数组A[p...r]进行快速排序的三步分治过程:

           分解:数组A[p...r]被划分为两个(可能为空)子数组A[p...q - 1]和A[q + 1...r],使得A[p...q - 1]中的每一个元素都小于或等于A[q],而A[q]也小于等于A[q + 1...r]中的每一个元素。其中计算下标q也是划分过程的一部分。

            解决:通过递归调用快速排序,对子数组A[p...q - 1]和A[q + 1...r]进行排序。

下面则分别实现quicksort.h和quicksort.c

#ifndef _QUICKSORT_H_
#define _QUICKSORT_H_

#define N 10
//接口声明
void Quicksort(int *data,int p,int r);
int Partition(int *data,int p,int r);
void print_array(int *data,int n);
#endif


对于接口的实现:

#include <stdio.h>
#include <stdlib.h>
#include "quicksort.h"

static void swap(int *a,int *b)
{
    int temp = 0;
    temp = *a;
    *a = *b;
    *b = temp;
}
void Quicksort(int *data,int p,int r)
{
    int q = 0;
    if(p < r){
        q = Partition(data,p,r);
        Quicksort(data,p,q - 1);
        Quicksort(data,q + 1,r);
    }
}

int Partition(int *data,int p,int r)
{
    int i = p - 1;
    int x = data[r];
    int j = 0;
    for(j = p;j <= r - 1;++j){
        if(data[j] < x){
            i = i + 1;
            swap(&data[i],&data[j]);
        }
    }
    swap(&data[i + 1],&data[r]);
    return i + 1;
}
void print_array(int *data,int n)
{
    int  i = 0;
    for(i = 0;i < n;++i){
        printf("%5d",data[i]);
    }
    printf("\n");
}

主程序:

#include <stdio.h>
#include <stdlib.h>
#include "quicksort.h"

int main(int argc ,char **argv)
{
    int data[N];
    int i = 0;

    srand(time(0));

    for(i = 0;i < N;++i){
        data[i] = rand() % 100;
    } 
    printf("排序前:\n");
    print_array(data,N);

    Quicksort(data,0,N - 1);

    printf("排序后:\n");
    print_array(data,N);    
    return 0;
}

程序执行结果:

快速排序的性能分析:
    快速排序的运行时间依赖于划分是否平衡,而平衡与否又依赖于用于划分的元素。如果划分是平衡的,那么快速排序算法性能与归并排序一样。如果划分是不平衡的,那么快速排序的性能就接近于插入排序了。

    最坏情况划分:当划分产生的两个子问题分别包含了n - 1个元素和0个元素时,快速排序的最坏情况发生了。不妨假设算法的每一次递归调用都出现了这种不平衡划分。划分操作的时间复杂度是o(n)。由于对一个大小为0的数组进行递归调用会直接返回,因此T(0) = O(1),于是算法的运行时间的递归式可以表示为:

     T(n)= T(n - 1)+T(0)+ o(n)= T(n - 1)+o(n)

利用代入法可以直接得到递归式T(n)= o(n * n)

    最好情况分析:在可能的最平衡的划分中,Partition得到的两个子问题的规模都不大于n / 2,这是因为其中一个子问题的规模为[n / 2],则另一个子问题的规模为[n / 2] - 1。在这种情况下,排序的性能非常好,此时,算法运行时间的递归式为;

    T(n) = 2T(n / 2)+ o(n)

根据定理,上述递归式的解为T(n) = o(n lgn)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值