STM32的HAL库开发系列 - 常用的用户库代码 - 快速排序

简介: STM32的HAL库开发系列 - 常用的用户库代码 - 快速排序

STM32的HAL库开发系列 - 常用的用户库代码 - 快速排序

快速排序算法

快速排序是一种高效的排序算法,它的基本思想是分治。分治的思想是将一个复杂的问题分成两个或更多的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

快速排序的基本思想是,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

在快速排序算法中,选取基准元素是非常重要的。一般来说,我们可以选取第一个元素作为基准元素,也可以选取最后一个元素作为基准元素,也可以选取中间元素作为基准元素,还可以随机选取一个元素作为基准元素。

算法过程

在快速排序中,选取第一个元素作为基准元素,然后使用两个指针i和j将数组分成三部分,其中左边部分的元素都小于基准元素,右边部分的元素都大于基准元素,中间部分的元素等于基准元素。

具体的实现过程如下:

首先在数组中选取一个基准元素,通常是第一个元素。
使用两个指针i和j,分别指向数组的第一个元素和最后一个元素。
从右往左扫描,如果发现比基准元素小的元素,就把它交换到左边的位置。
从左往右扫描,如果发现比基准元素大的元素,就把它交换到右边的位置。
重复上述过程直到i和j相遇。
把基准元素放到i和j相遇的位置。

这样,就把原数组分成了三部分,其中第一部分小于基准元素,第三部分大于基准元素,第二部分等于基准元素。

接下来,对第一部分和第三部分分别进行快速排序,递归地对子数组进行排序,直到整个数组有序。

详细的代码如下:

void quick_sort(int s[], int l, int r)
{
    if (l < r)
    {
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while(i < j && s[j] >= x) 
                j--;  
            if(i < j) 
                s[i++] = s[j];
            while(i < j && s[i] < x) 
                i++;  
            if(i < j) 
                s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s, l, i - 1); 
        quick_sort(s, i + 1, r);
    }
}

该代码中,参数s[]为待排序数组,l和r分别为数组的左右边界。首先判断数组长度是否为0或1,若是则无需排序。否则,选取数组的第一个元素作为基准元素x,然后使用两个指针i和j将数组分成三部分,其中左边部分的元素都小于x,右边部分的元素都大于x,中间部分的元素等于x。最后递归地对左边和右边的子数组进行快速排序,直到整个数组有序。

在上述代码中,第一重循环是主要的排序过程,其中i指针从左向右移动,j指针从右向左移动,当s[i]大于等于x时,j指针向左移动,当s[j]小于x时,i指针向右移动,当i<j时,交换s[i]和s[j]的值,继续移动i和j。循环结束后,s[i]的值一定等于x,这样就把数组分成了两部分,一部分元素小于x,一部分元素大于等于x。

然后递归地对左边和右边的子数组进行快速排序,直到整个数组有序。

总的来说快排的时间复杂度为 O(nlogn),是一种高效的排序算法。

那么如何让代码更加简洁一些呢?可以参考接下来我的这段代码

void Quick_Sort(int16_t q[], int16_t l, int16_t r, bool_t order)
{
    if (l >= r) return;
    int16_t i = l - 1, j = r + 1, x = q[(l + r) >> 1];
    while (i < j) {
        if (order) {
            do i ++ ; while (q[i] < x);
            do j -- ; while (q[j] > x);
        } else {
            do i ++ ; while (q[i] > x);
            do j -- ; while (q[j] < x);
        }
        if (i < j) {
            int16_t k = q[i];
            q[i] = q[j];
            q[j] = k;
        }
    }
    Quick_Sort(q, l, j, order), Quick_Sort(q, j + 1, r, order);
}
目录
相关文章
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
702 0
|
1月前
【寄存器开发速成】半小时入门STM32寄存器开发(二)
【寄存器开发速成】半小时入门STM32寄存器开发(二)
|
1月前
|
芯片
【寄存器开发速成】半小时入门STM32寄存器开发(一)
【寄存器开发速成】半小时入门STM32寄存器开发(一)
|
5月前
|
存储 数据采集 数据安全/隐私保护
使用STM32F103读取TF卡并模拟U盘:使用标准库实现
通过以上步骤,你可以实现用STM32F103将TF卡内容变成U盘进行读取。这种功能在数据采集、便携式存储设备等应用中非常有用。如果你有更多的需求,可以进一步扩展此项目,例如添加文件管理功能、加密存储等。希望这篇博客能帮到你,如果有任何问题,欢迎在评论区留言讨论!
230 1
|
4月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
157 0
|
5月前
|
存储 数据安全/隐私保护 芯片
【STM32】详解嵌入式中FLASH闪存的特性和代码示例
【STM32】详解嵌入式中FLASH闪存的特性和代码示例
【STM32】详解独立看门狗的本质和使用步骤&代码
【STM32】详解独立看门狗的本质和使用步骤&代码
|
5月前
|
传感器 数据格式
【STM32】DHT11温湿度模块传感器详解&代码
【STM32】DHT11温湿度模块传感器详解&代码
|
5月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
432 2
|
6月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结