快速排序

编辑中。。。

快速排序通常明显比同为Ο(n log n)的其他算法更快,因此常被采用,而且快排采用了 分治法 的思想,所以在很多笔试面试中能经常看到快排的影子。

基本思路

快速排序是基于分治模式处理的,对一个典型子数组A[p…r]排序的分治过程为三个步骤:

  1. 分解:

    A[p..r]被划分为两个(可能空)子数组A[p ..q-1]和A[q+1 ..r],使得
    
    A[p ..q-1] <=  A[q]  <= A[q+1 ..r]
    
  2. 解决:通过递归调用快速排序,对子数组A[p ..q-1]和A[q+1 ..r]排序。

  3. 合并。

时间复杂度:平均,O(nlogn);最好,O(nlogn);最差,O(n^2)

划分方法1

void qs1(int left,int right)
{
    if (left >= right)
        return;
    int i = left;
    int j = right;
    int fg = arr[left];
    while (i<j)
    {
        while (j > i && arr[j] <= fg)
        {
            j--;
        }
        while (i < j && arr[i] >= fg)
        {
            i++;
        }
        if ( i < j )
            swap(arr[i], arr[j]);
    }
    swap(arr[left],arr[i]);
    qs1(left, i-1);
    qs1(i+1, right);
}

划分方法2

int partition(int left, int right)
{
    int pivot = arr[right];
    int i = left;
    int j = left;
    while (j < right)
    {
        if (arr[j] < pivot)
        {
            swap(arr[j], arr[i++]);
        }
        j++;
    }
    swap(arr[right], arr[i]);
    return i;
}

void qs2(int left, int right)
{
    if (left < right)
    {
        int mid = partition(left, right);
        qs2(left, mid - 1);
        qs2(mid + 1, right);
    }
}

测试:

#include <iostream>
#include <algorithm>
#include <iterator>

using namespace std;

int arr[10] = {6,1,20,7,9,3,4,5,10,8};

void qs1(int left,int right)
{
    if (left >= right)
        return;
    int i = left;
    int j = right;
    int fg = arr[left];
    while (i<j)
    {
        while (j > i && arr[j] <= fg)
        {
            j--;
        }
        while (i < j && arr[i] >= fg)
        {
            i++;
        }
        if ( i < j )
            swap(arr[i], arr[j]);
    }
    swap(arr[left],arr[i]);
    qs1(left, i-1);
    qs1(i+1, right);
}

int partition(int left, int right)
{
    int pivot = arr[right];
    int i = left;
    int j = left;
    while (j < right)
    {
        if (arr[j] < pivot)
        {
            swap(arr[j], arr[i++]);
        }
        j++;
    }
    swap(arr[right], arr[i]);
    return i;
}

void qs2(int left, int right)
{
    if (left < right)
    {
        int mid = partition(left, right);
        qs2(left, mid - 1);
        qs2(mid + 1, right);
    }
}

int main()
{
// qs1(0, 9);
    qs2(0, 9);

    copy(begin(arr), end(arr), ostream_iterator<int>(cout, " "));

    return 0;
}

你可能感兴趣的:(快速排序)