再谈快速排序

本篇博客是在快速排序基础上优化的。

算法思想

快速排序是基于分治模式构思的,具体描述如下:

  • 分解:数组A[p..r]被划分成两个(可能空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每个元素都小于等于A(q),而且,小于等于A[q+1..r]中的元素。下标q也在这个划分过程中进行计算。
  • 解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]排序。
  • 合并:因为两个子数组是就地排序的,将它们合并不需要操作:整个数组A[p..r]已排序。
// QUICKSORT
QUICKSORT(A, p, r)
   if p < r
      then  q = PARTITION(A, p, r)
            QUICKSORT(A, p, q-1)
            QUICKSORT(A, q+1, r)

// PARTITION
PARTITION(A, p, r)
   x = A[r]
   i = p-1
   for j = p to r-1
        do if A[j] <= x
            then i = i+1
                exchange(A[i], A[j])
   exchange(A[i+1], A[r])
   return i+1

算法解析

具体执行步骤如下:

  • i=p-1, j=p, x=A[r]
  • 因为A[i]<=x,i=p,A[i]和A[j]交换
  • A[j]=7>x,j递增
  • 当A[j]=1时,因为A[i]<=x,i=p+1,A[i]和A[j]交换
  • 当A[j]=3时,因为A[i]<=x,i=p+2,A[i]和A[j]交换
  • A[j]=5>x,j递增
  • A[j]=6>x,j递增
  • j=r,A[r]和A[i+1]交换

源程序

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h> 
#include <sys/time.h>
void swap(int &x, int &y); 
int partition(int *array, int left, int right); 
void qsort(int *array, int left, int right);
void print(int *array, int left, int right);
void print(int *array, int n);
void input(int *&array, int n);

const int number = 8;

int main(int argc, char *argv[])
{
    //int array[] = {13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 11};
    int array[] = {2, 8, 7, 1, 3, 5, 6, 4};
    //int *array = new int[number];
    int n = number;
    //input(array, number);

    printf("befor qsort\n");
    print(array, n);
    printf("\n");

    struct timeval stv;
    gettimeofday(&stv, NULL);
    int st_usec = stv.tv_sec * 1000000 + stv.tv_usec;

    qsort(array, 0, n - 1);
    struct timeval end_tv;
    gettimeofday(&end_tv, NULL);
    int end_usec = end_tv.tv_sec * 1000000 + end_tv.tv_usec;
    int cost = end_usec - st_usec;
    printf("qsort cost time : %dus\n", cost);

    printf("after qsort\n");
    print(array, n);
    //delete []array;
    exit(0);
}

void qsort(int *array, int left, int right)
{
    if (left < right)
    {
        //print(array, 0, number - 1);
        int pos = partition(array, left, right);
        qsort(array, left, pos - 1);
        qsort(array, pos + 1, right);
    }
}

int partition(int *array, int left, int right)
{
    printf("before partition\n");
    print(array, 0, number - 1);
    int i = left - 1;
    int x = array[right];

    for (int j = left; j < right; j++)
    {
        printf("in partition : ");
        if (array[j] <= x)
        {
            ++i;
            swap(array[i], array[j]);
        }
        //print(array, 0, number - 1);
        print(array, left, right);
        //printf("in partition\n");
    }

    swap(array[i + 1], array[right]);
    printf("after partition\n");
    print(array, 0, number - 1);
    printf("\n");
    return i + 1;
}

void swap(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

void print(int *array, int left, int right)
{
    for (int i = left; i <= right; i++)
    {
        printf("%d ", array[i]);
    }
    printf("\n");
}

void print(int *array, int n)
{
    print(array, 0, n - 1);
}

void input(int *&array, int n)
{
    for (int i = 0; i < n; i++)
    {
        array[i] = rand() % n;
    }
}

算法执行过程

befor qsort
2 8 7 1 3 5 6 4 

before partition
2 8 7 1 3 5 6 4 
in partition : 2 8 7 1 3 5 6 4 
in partition : 2 8 7 1 3 5 6 4 
in partition : 2 8 7 1 3 5 6 4 
in partition : 2 1 7 8 3 5 6 4 
in partition : 2 1 3 8 7 5 6 4 
in partition : 2 1 3 8 7 5 6 4 
in partition : 2 1 3 8 7 5 6 4 
after partition
2 1 3 4 7 5 6 8 

before partition
2 1 3 4 7 5 6 8 
in partition : 2 1 3 
in partition : 2 1 3 
after partition
2 1 3 4 7 5 6 8 

before partition
2 1 3 4 7 5 6 8 
in partition : 2 1 
after partition
1 2 3 4 7 5 6 8 

before partition
1 2 3 4 7 5 6 8 
in partition : 7 5 6 8 
in partition : 7 5 6 8 
in partition : 7 5 6 8 
after partition
1 2 3 4 7 5 6 8 

before partition
1 2 3 4 7 5 6 8 
in partition : 7 5 6 
in partition : 5 7 6 
after partition
1 2 3 4 5 6 7 8 

qsort cost time : 3610us
after qsort
1 2 3 4 5 6 7 8 

算法复杂度分析

时间复杂度空间复杂度说明
最优情况O(nlogn)O(logn)
平均情况O(nlogn)O(logn)
最坏情况O(n^2)O(n)

算法耗时分析

数量级耗时说明
1万1.7ms
1百万238ms
1千万2.5s
2千万5.4s
5千万14s
1亿内存空间有限

参考文献

[1] Thomas H.Cormen, Charles E.Leiserson,etc. 算法导论

当谈到快速排序算法时,有多种变体和优化方法可供选择。以下是几个常见的快速排序算法的实现示例,使用 Python 编程语言: 1. 基本快速排序算法: ```python def quicksort_basic(arr): if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] less, equal, greater = [], [], [] for num in arr: if num < pivot: less.append(num) elif num == pivot: equal.append(num) else: greater.append(num) return quicksort_basic(less) + equal + quicksort_basic(greater) ``` 2. 优化快速排序算法(使用随机选择枢轴元素): ```python import random def quicksort_optimized(arr): if len(arr) <= 1: return arr pivot = random.choice(arr) less, equal, greater = [], [], [] for num in arr: if num < pivot: less.append(num) elif num == pivot: equal.append(num) else: greater.append(num) return quicksort_optimized(less) + equal + quicksort_optimized(greater) ``` 3. 优化快速排序算法(使用三数取中法选择枢轴元素): ```python def quicksort_median_of_three(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 pivot = sorted([arr[0], arr[mid], arr[-1]])[1] less, equal, greater = [], [], [] for num in arr: if num < pivot: less.append(num) elif num == pivot: equal.append(num) else: greater.append(num) return quicksort_median_of_three(less) + equal + quicksort_median_of_three(greater) ``` 以上是一些常见的快速排序算法的实现示例,你可以根据自己的需要选择适合的算法。快速排序算法的时间复杂度通常为 O(nlogn),在大多数情况下表现良好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值