STM32的HAL库开发系列 - 常用的用户库代码1
这些STM32用户库代码是一组预先写好的程序,可以帮助更快、更容易地开发STM32应用程序。
这些代码通常包括驱动程序、硬件抽象层、中间件和示例应用程序。使用库代码可以减少开发时间和提高代码质量,使开发人员能够专注于应用程序的业务逻辑。
快速计算平方根的倒数
/**
* @brief 快速计算平方根的倒数
* @param[in] number
* @notice See: http://en.wikipedia.org/wiki/Fast_inverse_square_root
*/
float invSqrt(float number)
{
const float x2 = number * 0.5f;
const float threehalfs = 1.5f;
union {
float f;
uint32_t i;
} conv = { .f = number };
conv.i = 0x5f3759df - ( conv.i >> 1 );
conv.f *= threehalfs - ( x2 * conv.f * conv.f );
return conv.f;
}
快速排序
快速排序是一种分治算法。
它的基本思想是选择一个基准元素,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序是一种高效且常见的排序算法。它采用了分治的策略,将待排序的数组分成两部分,其中一部分元素都比另一部分元素小。这样就可以对每一部分分别进行排序,继而达到将整个数组有序的目的。
具体来说,快速排序首先在数组中选取一个元素作为“基准元素”,再使用两个指针对数组进行遍历,将数组分为三部分:小于基准元素,等于基准元素和大于基准元素。接着,对小于基准元素的部分和大于基准元素的部分分别进行快速排序,直到整个数组有序。
快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn),是一种非常高效的排序算法。在实际应用中,快速排序经常用来解决大规模数据的排序问题。
最后需要注意的是,选取基准元素的方式会影响到算法的效率,通常选取中间元素或随机选取元素可以使算法更加高效。
/**
* @brief 快速排序
* @param[out] q : 待排数组
* @param[in] l / r : 左右端点(闭区间
* @param[in] order 0为从小到大升序 1为从大到小降序
*/
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);
}
另外,在实际实现中,对于小数组或者数组中元素都相同的情况,应该使用插入排序或其他算法来优化快排。这样可以避免因为基准元素选择不当或者递归深度过深而导致的时间复杂度退化的问题。
需要指出的是,快速排序的稳定性是不稳定的,因为在交换元素的过程中会改变元素的相对顺序。如果需要稳定排序,可以使用归并排序或桶排序。
在实现快速排序时,需要注意一些细节,如递归和非递归的实现方式,基准元素的选择策略以及对于小数组的优化等。
另外,快排的常见优化有:三数取中(避免最坏情况),小区间采用插入排序(小数据量时效率更高),荷兰国旗问题(Partition)。
总的来说,快速排序是一种高效的排序算法,它的实现简单,对于大部分数据都能达到较好的效率。同时,它也是一种可以并行化的算法,在多核处理器环境下能够更加高效。它在时间复杂度和空间复杂度上都十分优秀,在许多场景下都可以使用。