快速排序

本文详细介绍了快速排序算法的原理及其实现过程。通过选取基数并利用分治思想,快速排序能够高效地对数组进行排序。文章提供了详细的步骤说明,并附带了完整的C++实现代码。

快速排序

原理:

快速排序作为最经典的排序算法之一,一直深受各大面试公司和研究生入学考试的青睐。作为一中不稳定的、In-place排序,快排有着其不可逾越的高效性,其排序效率在同等O(n*lgN)的几种排序中最高。

该算法的基本思想如下:

  1. 从数组中选取一个基数,作为参照。

  2. 接下来我们的目标就是在数组中为这个基数找到一个适当的位置,使得位于基数前的数字均小于基数,位于基数后的数字均大于基数。(具体方法见下)

  3. 然后分别对基数左侧和右侧的数组分别进行步骤2的推到过程,直到每个数组只有一个数。

从上面的推导中可以看出,快速排序是基于分治思想的,通过逐步缩小排序范围,来将大问题分解为小问题。接下来我们主要介绍步骤2的具体实施过程。

假设我们有如下数组 a:

012345678
6234895010876486467

首先,我们选取第一个元素作为基数 base(改进版的快速排序可以通过随机选取基数达到改进算法的目的),这里我们默认使用第一个元素,即a[0] 。此时,相当于从数组中将a[0]抠出来了,数组如下:

0(i)12345678(j)
34895010876486467

然后,记住我们的目标是在数组中为基数base找到一个有序的位置,把比base大的数丢到其右边,比base小的数丢到其左边。

做一些初始化的工作, i=0,j=8, 此时 base = 62

1) 从 j 开始,从右向左遍历数组,找到一个比 base 小的数。

如果 a[j]>=base,则 j– 。直到 j=6,符合条件,将 a[j] 丢到空白处,即。此时 a[i] = a[j],第 j 个元素右侧的元素均大于 base,第 i 个元素左侧的元素均小于 base。

01(i)23456(j)78
48348950108766467

2) 从 i 开始,从左向右遍历数组,找到一个比 base 小的数。

如果 a[i]<=base,则 i++ 。直到 i=2 ,符合条件,将 a[i] 丢到空白处,即 a[j] = a[i] ,j– 。此时,第 j 个元素右侧的元素均大于 base,第 i 个元素左侧的元素均小于 base。

012 (i) 345(j)678
48345010876896467

3) 重复1)、2)的过程,先从后向前找,再从前向后找,直到 i >= j, a[i] = base 。

0123 (i)(j) 45678
48345010876896467

此时,i >=j , a[i] = base

0123 (i)(j) 45678
4834 506210876896467

最后,分别对区间[0,2]和[4,8]重复1)、2)、3)的过程。

代码:

#include<iostream>
#define MAX 100
using namespace std;

/*
输出数组arr,如果flag为0,则升序输出;否则,逆序输出。
arr:数组
n:数组长度
flag:输出标志
*/
void Output(int arr[],int n,int flag)
{
    int i;
    if(flag == 0)
    {
        for(i=0;i<n;i++)
        {
            if(i!= n-1)
            {
                cout<<arr[i]<<" ";
            }
            else{
                cout<<arr[i]<<endl;
            }
        }
    }
    else
    {
        for(i=n-1;i>=0;i--)
        {
            if(i!= 0)
            {
                cout<<arr[i]<<" ";
            }
            else{
                cout<<arr[i]<<endl;
            }
        }
    }
}

/*
快速排序
arr:待排序数组
s:待排序区间左端点
n:待排序区间右端点
*/
void QuickSort(int arr[],int s,int n)
{
    if(s >= n)
    {
        return;
    }
    int i=s,j=n;
    int base = arr[i];//基数
    while(i != j)
    {
        while(arr[j] >= base && i != j)//对右侧排序
        {
            j--;
        }
        if(i != j)
        {
            arr[i] = arr[j];
            i++;
            while(arr[i] <= base && i!= j)//对左侧排序
            {
                i++;
            }
            if(i != j)
            {
                arr[j] = arr[i];
                j--;
            }
        }
    }
    arr[i] = base;
    QuickSort(arr,s,i-1);//对base左侧排序
    QuickSort(arr,i+1,n);//对base右侧排序
}

int main(void)
{
    int i,n,flag;
    int arr[MAX];
    cin>>n;//输入元素个数
    for(i=0;i<n;i++)
    {
        cin>>arr[i];
    }
    cin>>flag;//输入输出标志。如果flag为0,则升序输出;否则,逆序输出。
    QuickSort(arr,0,n-1);
    Output(arr,n,flag);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值