Quick Sort及应用

本文详细介绍了快速排序算法的实现原理及步骤,并通过实例演示了如何使用快速排序算法对数组进行排序。此外,还提供了求解数组中第k小元素的具体方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法原理

定义quick_sort函数,对A[left..right]进行排序

首先检查数组大小,若数组大小为1或为空,则直接返回

然后调用partition函数,返回pivot为数组中的某个位置,位于pivot之前的元素A[left..pivot-1]均小于A[pivot],位于pivot之后的元素A[pivot+1..right]均大于A[pivot]

最后递归调用quick_sort函数,对pivot分开的两部分A[left..pivot-1]A[pivot+1..right]进行排序

void quick_sort( vector<int>& A, int left, int right )
{
    if( left >= right )
        return;

    int pivot = partition( A, left, right );

    quick_sort( A, left, pivot - 1 );
    quick_sort( A, pivot + 1, right );
}

定义partition函数

int partition( vector<int>& A, int left, int right )
{
    while( left < right )
    {
        while( left < right && A[left] <= A[right] )
            right--;

        swap( A[left], A[right] );  // 违反了A[left] <= A[right],把它们交换

        while( left < right && A[left] <= A[right] )
            left++;

        swap( A[left], A[right] );
    }

    return left;    // 最终left和right相等
}

(1)固定left,移动right,找到第一处A[left] > A[right]的位置(违反升序),交换它们

(2)固定right,移动left,找到第一处A[left] > A[right]的位置(违反升序),交换它们

上述(1)(2)两步交替进行,直到leftright相等,即为pivot的位置

注:第6行right--第11行left++可以交换
这里写图片描述

完整代码如下

#include <stdio.h>
#include <time.h>
#include <vector>
#include <algorithm>
#define MAXN 50
using namespace std;



void display( vector<int>& s )
{
    for( int i = 0; i < s.size(); i++ )
        printf( "%d ", s[i] );
    printf( "\n" );
}

bool check( vector<int>& s1, vector<int>& s2 )
{
    for( int i = 0; i < s1.size(); i++ )
        if( s1[i] != s2[i] )
            return false;   
    return true;
}



int partition( vector<int>& A, int left, int right )
{
    while( left < right )
    {
        while( left < right && A[left] <= A[right] )
            right--;

        swap( A[left], A[right] );  // 违反了A[left] <= A[right],把它们交换

        while( left < right && A[left] <= A[right] )
            left++;

        swap( A[left], A[right] );
    }

    return left;    // 最终left和right相等
} 

void quick_sort( vector<int>& A, int left, int right )
{
    if( left >= right )
        return;

    int pivot = partition( A, left, right );

    quick_sort( A, left, pivot - 1 );
    quick_sort( A, pivot + 1, right );
}



int main()
{
    srand( (unsigned)time(NULL) );

    int nums[MAXN];

    for( int i = 0; i < MAXN; i++ )
        nums[i] = rand() % 100;

    vector<int> s1( nums, nums + MAXN );
    vector<int> s2( nums, nums + MAXN );

    quick_sort( s1, 0, s1.size() - 1 );
    sort( s2.begin(), s2.end() );

    printf( "s1: " );
    display(s1);

    printf( "s2: " );
    display(s2);

    printf( "Result: %s\n", check( s1, s2 ) ? "Accepted" : "Wrong Answer" );

    return 0;
}

应用:数组中的第k小(大)

LeetCode 215. Kth Largest Element in an Array
因为是从大到小数第k个,所以利用partition函数(降序版)解决

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        return helper( nums, k, 0, nums.size() - 1 );
    }

    int helper( vector<int>& nums, int k, int left, int right )
    {
        int pivot = partition( nums, left, right );
        int len1 = pivot - left + 1;

        if( k == len1 )
            return nums[pivot];
        else if( k < len1 )
            return helper( nums, k, left, pivot - 1 );
        else
            return helper( nums, k - len1, pivot + 1, right );
    }

    int partition( vector<int>& nums, int left, int right )
    {
        while( left < right )
        {
            while( left < right && nums[left] >= nums[right] )  // 降序版
                right--;

            swap( nums[left], nums[right] );

            while( left < right && nums[left] >= nums[right] )  // 降序版
                left++;

            swap( nums[left], nums[right] );
        }

        return left;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值