排序算法——快速排序

本文详细介绍了快速排序算法的基本思想和步骤,通过实例演示了快速排序的过程,并提供了算法的伪代码实现。

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

算法思想

快速排序的主要思想就是:分治+快速排序

分治思想

    将原问题分解成若干规模更小但是结构和原问题相同的子问题。递归求解子问题,然后解出原问题。

快排算法思想

  1. 选择数组中第一个数作为基数,然后设置下标i=first,j=last
  2. 从数组后面找出比基数小的数调换到前面
  3. 然后从数组前面找出比基数大的数调换到后面
  4. 如此循环2-3步,直到i==j

结果为以基数分界,左边的数比全部比基数小,右边的数比基数大。结束这次排序

然后,下次分别排序[first,i-1]和[i+1,last],使序列左边有序和右边有序

这是一个递归的过程,直到first > i-1或者i+1 > last 返回

这样就将原问题划分成两个与原问题相同的子问题,再次对这两个区间进行快速排序。

算法演示

还是以序列3,2,5,6,4,7,1为例
开始的时候以第一个数3为基数,3所处的位置就相当于一个坑,空出来
base = 3;i = 0;j = 6;

256471
0123456
ij

从后往前找小于基数的的数,找到最后一个数1,于是将1填在位置0,位置6就被空出来了, i++向中间移位

125647
0123456
ij

从前往后找大于基数的数,找到5,于是将5填在位置6,位置2就被空出,j--向中间移位

126475
0123456
ij

然后又从后往前找,找小于基数的数,当j==i时,结束本次排序。
最后基数插入空出的位置2

1236475
0123456
i j

可以发现,基数左边的数都小于基数,右边的数都大于基数以基数分界,下次排序就分别排序列[first,i-1]和[i+1,last]即序列[1,2]和[6,4,7,5]


排序序列[1,2]
基数为0
i=0;j=1;
从后往前找,因为只有一个数且大于1,因此在i==j后,1仍旧插入位置0
本次排序结束
因为i-1=-1 小于本次排序中的first 0,所以本序列不在进行划分排序


排序序列[6,4,7,5]
base = 6; i = first ; j=last;
即i=3,j=6

475
3456
ij

从后往前找小于6的数,找到5,将其填入位置0,位置6就空出来了。然后i++,向中间移位

547
3456
ij

从前往后找大于6的数,找到7,于是将7填入位置6,位置5就空出,然后j--,向中间移位

547
3456
i j

因为i==j,所以结束本次排序,将6插入i所指的位置。

5467
3456
i j

此次继续排序[first,i-1]和[i+1,last]即[5,4]和[7]

因为i+1 == last 所以不在进行排序

排序[5,4]类似于排序前面的序列[1,2],只不过序列[5,4]排序后为[4,5]

最终序列变得有序

算法代码实现

//分治
void QuickSort(int a[],int first,int last)
{
    if(first < last)
    {
        int i = AdjustArray(a,first,last);//以基数分界,对基数左边快排,对基数右边快排
        QuickSort(a,first,i-1);
        QuickSort(a,i+1,last);
    }
}

//快速排序的代码(可以理解为挖坑填数)
int AdjustArray(int a[],int first,int last)
{
    int i = first,j = last;
    int m = a[first];//以第一个数为基数

    while(i<j)
    {
        while(i<j && a[j] >= m)//从后往前找小于基数的数
            j--;
        if(i<j)
        {
            a[i] = a[j];//将a[j]填到a[i],a[j]变成一个坑
            i++;
        }

        while(i<j && a[i] < m)//从前往后找比基数大的数
            i++;
        if(i<j)
        {
            a[j] = a[i];//将a[i]填到a[j],a[i]变成一个坑
            j--;
        }
    }
    a[i] = m;//退出时,i=j,将基数填入坑中
    return i;
}

转载于:https://www.cnblogs.com/myworld7/p/10591133.html

### 快速排序分治算法实现原理 快速排序是一种基于分治策略的经典排序算法,其核心思想是通过选取一个基准值(Pivot),将待排序数组划分为两个子数组,使得左侧子数组的元素均不大于基准值,右侧子数组的元素均不小于基准值。随后递归地对这两个子数组进行相同的操作,直到每个子数组只有一个元素或为空为止。 #### 1. 快速排序的核心思想 快速排序的关键在于如何有效地划分数组以及递归处理子数组的过程。具体来说,快速排序可以分解为以下几个阶段[^2]: - **选择基准值 (Pivot)**:通常可以选择第一个元素、最后一个元素或者随机选择某个元素作为基准值。 - **分区操作 (Partition)**:重新排列数组,使所有小于基准值的元素位于左边,所有大于基准值的元素位于右边,并返回基准值的位置索引。 - **递归排序**:对基准值两侧的子数组分别递归应用相同的分区和排序逻辑。 最终的结果是,当所有的子数组都被排序完成后,整个数组也变得有序。 #### 2. 时间复杂度分析 快速排序的时间性能取决于每次分割后的子数组大小分布情况。理想情况下,如果每次都能均匀地将数组一分为二,则时间复杂度为 \( O(N \log N) \)[^4]。然而,在最坏的情况下(例如输入数组已经完全逆序或顺序排列),可能会退化至线性平方级的时间复杂度 \( O(N^2) \)。 #### 3. 空间复杂度 由于快速排序采用的是原地排序方式,因此不需要额外分配大量的存储空间来保存临时副本。除了用于记录递归调用栈的空间外,几乎无需其他辅助内存资源消耗。对于平均情况而言,递归深度大约为 \( \log N \),故总体空间复杂度接近于 \( O(\log N) \)[^2]。 #### 4. Python 实现代码示例 以下是使用Python编写的快速排序函数的一个简单版本: ```python def quick_sort(arr): if len(arr) <= 1: return arr else: pivot = arr[len(arr)//2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) # 测试例子 example_array = [3,6,8,10,1,2,1] print("Sorted array:", quick_sort(example_array)) ``` 此段程序展示了基本的功能框架,实际工程环境中可能还需要考虑更多边界条件及优化措施。 #### 5. 不稳定性的讨论 值得注意的一点是,尽管快速排序效率很高,但它并非总是稳定的排序方法。所谓稳定性是指相等键值的数据项在排序之后能够保持原有的相对次序不变。而因为我们在上面给出的例子中直接丢弃了关于位置的信息,所以在某些特定场景下可能导致原本相邻重复数值被打散重组从而破坏原有秩序关系[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值