0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32采集傳感器數(shù)據(jù)通過冒泡排序取穩(wěn)定值

DS小龍哥-嵌入式技術(shù) ? 來源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2023-05-25 14:14 ? 次閱讀

一、前言

物聯(lián)網(wǎng)、單片機開發(fā)中,經(jīng)常需要采集各種傳感器的數(shù)據(jù)。比如:溫度、濕度、MQ2、MQ3、MQ4等等傳感器數(shù)據(jù)。這些數(shù)據(jù)采集過程中可能有波動,偶爾不穩(wěn)定,為了得到穩(wěn)定的值,我們可以對數(shù)據(jù)多次采集,進行排序,去掉最大和最小的值,然后取平均值返回。

image-20230525140855726

image-20230525140932125

二、排序算法

【1】冒泡排序

冒泡排序(Bubble Sort)是一種簡單的排序算法,也是最基礎(chǔ)、最容易理解的一種排序算法。它會遍歷要排序的數(shù)組,依次比較相鄰兩個元素的大小,如果前一個元素比后一個元素大,就交換這兩個元素的位置。

冒泡排序的過程如下:

  1. 從數(shù)組的第一個元素開始,依次比較相鄰的兩個元素,如果前一個元素比后一個元素大,則交換這兩個元素的位置。
  2. 繼續(xù)比較相鄰的元素,直到數(shù)組的最后一個元素。
  3. 重復執(zhí)行步驟1和步驟2,直到整個數(shù)組都按照從小到大的順序排列好。

冒泡排序的時間復雜度是O(N^2),其中N是數(shù)組中元素的數(shù)量。在實際應(yīng)用中,由于其時間復雜度較高,冒泡排序很少被用于大規(guī)模數(shù)據(jù)的排序,但它仍然是一種優(yōu)秀的教學工具,因為它容易理解和實現(xiàn),并且可以幫助初學者理解排序算法的基本思想。

以下是C語言代碼的實現(xiàn),封裝為名為calculateAverage的函數(shù)。

#define ARRAY_SIZE 20
 ?
 // 冒泡排序算法函數(shù)
 void bubbleSort(int arr[], int n) {
     for(int i = 0; i < n-1; i++) {
         for(int j = 0; j < n-i-1; j++) {
             if(arr[j] > arr[j+1]) {
                 int temp = arr[j];
                 arr[j] = arr[j+1];
                 arr[j+1] = temp;
             }
         }
     }
 }
 ?
 // 計算平均值函數(shù),去除最大值和最小值
 int calculateAverage() {
     int arr[ARRAY_SIZE];
     // 連續(xù)讀取20次數(shù)據(jù)
     for(int i = 0; i < ARRAY_SIZE; i++) {
         arr[i] = ReadADC();
     }
     // 對數(shù)組進行排序
     bubbleSort(arr, ARRAY_SIZE);
     // 去掉最大值和最小值
     int sum = 0;
     for(int i = 1; i < ARRAY_SIZE-1; i++) {
         sum += arr[i];
     }
     // 計算平均值并返回
     return sum / (ARRAY_SIZE-2);
 }

在函數(shù)中,首先定義了一個常量ARRAY_SIZE表示需要讀取的數(shù)據(jù)的數(shù)量。然后,使用一個循環(huán)讀取20次數(shù)據(jù),并將它們存儲到一個數(shù)組中。接著,用冒泡排序算法對數(shù)組進行排序。在排序完成后,計算數(shù)組中除去最大值和最小值的元素之和,并計算平均值。最后,返回計算得到的平均值。

【2】插入排序

插入排序(Insertion Sort)是一種簡單直觀的排序算法,它的基本思想是將一個元素插入到已排序好的序列中的適當位置,使得插入后仍然有序。

插入排序的過程如下:

  1. 假設(shè)第一個元素已經(jīng)是排好序的序列,從第二個元素開始,依次將每個元素插入到已經(jīng)排好序的序列中。
  2. 每次從未排序的部分中取出一個元素,與已排序的序列中的元素從后向前依次比較,找到插入的位置,即找到一個比當前元素小的值或者已經(jīng)到了開頭位置。
  3. 將當前元素插入到已排序序列的合適位置上,重新調(diào)整已排序的序列,繼續(xù)對未排序的序列進行排序。
  4. 重復執(zhí)行步驟2和步驟3,直到整個數(shù)組都按照從小到大的順序排列好。

插入排序的時間復雜度是O(N^2),其中N是數(shù)組中元素的數(shù)量。在實際應(yīng)用中,插入排序通常適用于處理小規(guī)模數(shù)據(jù)或者已經(jīng)接近有序的數(shù)據(jù),因為此時插入排序的效率高于其他排序算法。

以下是C語言代碼的實現(xiàn),封裝為名為calculateAverage的函數(shù)。

#define ARRAY_SIZE 20
 ?
 // 插入排序算法函數(shù)
 void insertionSort(int arr[], int n) {
     for(int i = 1; i < n; i++) {
         int key = arr[i];
         int j = i-1;
         while(j >= 0 && arr[j] > key) {
             arr[j+1] = arr[j];
             j--;
         }
         arr[j+1] = key;
     }
 }
 ?
 // 計算平均值函數(shù),去除最大值和最小值
 int calculateAverage() {
     int arr[ARRAY_SIZE];
     // 連續(xù)讀取20次數(shù)據(jù)
     for(int i = 0; i < ARRAY_SIZE; i++) {
         arr[i] = ReadADC();
     }
     // 對數(shù)組進行排序
     insertionSort(arr, ARRAY_SIZE);
     // 去掉最大值和最小值
     int sum = 0;
     for(int i = 1; i < ARRAY_SIZE-1; i++) {
         sum += arr[i];
     }
     // 計算平均值并返回
     return sum / (ARRAY_SIZE-2);
 }

在函數(shù)中,首先定義了一個常量ARRAY_SIZE表示需要讀取的數(shù)據(jù)的數(shù)量。然后,使用一個循環(huán)讀取20次數(shù)據(jù),并將它們存儲到一個數(shù)組中。接著,用插入排序算法對數(shù)組進行排序。在排序完成后,計算數(shù)組中除去最大值和最小值的元素之和,并計算平均值。最后,返回計算得到的平均值。

【3】希爾排序

希爾排序(Shell Sort)是一種由Donald Shell在1959年發(fā)明的排序算法,它是插入排序的一種變體,旨在減少排序中元素的移動次數(shù),從而使算法更快。希爾排序的基本思想是把數(shù)組中相距某個“增量”的元素組成一個子序列,對每個子序列進行插入排序,然后逐步縮小增量,重復進行上述操作,直到增量為1,最后再對整個數(shù)組進行一次插入排序。

希爾排序的過程如下:

  1. 選擇一個增量序列,將待排序的數(shù)組按照這個增量序列分成若干組(子序列)。通常,在第一次排序時,增量取數(shù)組長度的一半,以后每次將增量減半,直到增量為1。
  2. 對每個子序列進行插入排序,即將每個子序列中的元素按照遞增的順序插入到已排序好的序列中。
  3. 重復執(zhí)行步驟2,改變增量,直到增量為1。
  4. 最后再對整個數(shù)組進行插入排序。

希爾排序的時間復雜度與所選取的增量序列有關(guān)。最壞情況下的時間復雜度為O(N^2),其中N是數(shù)組中元素的數(shù)量。但在大多數(shù)情況下,希爾排序的時間復雜度優(yōu)于O(N^2),可以達到O(N log N)的級別。希爾排序的空間復雜度為O(1),因為它在排序過程中只需要常數(shù)個額外的存儲空間。

以下是C語言代碼實現(xiàn),封裝為名為calculateAverage的函數(shù)。

#define ARRAY_SIZE 20
 ?
 // 希爾排序算法函數(shù)
 void shellSort(int arr[], int n) {
     for(int gap = n/2; gap > 0; gap /= 2) {
         for(int i = gap; i < n; i++) {
             int temp = arr[i];
             int j;
             for(j = i; j >= gap && arr[j-gap] > temp; j -= gap) {
                 arr[j] = arr[j-gap];
             }
             arr[j] = temp;
         }
     }
 }
 ?
 // 計算平均值函數(shù),去除最大值和最小值
 int calculateAverage() {
     int arr[ARRAY_SIZE];
     // 連續(xù)讀取20次數(shù)據(jù)
     for(int i = 0; i < ARRAY_SIZE; i++) {
         arr[i] = ReadADC();
     }
     // 對數(shù)組進行排序
     shellSort(arr, ARRAY_SIZE);
     // 去掉最大值和最小值
     int sum = 0;
     for(int i = 1; i < ARRAY_SIZE-1; i++) {
         sum += arr[i];
     }
     // 計算平均值并返回
     return sum / (ARRAY_SIZE-2);
 }

在函數(shù)中,首先定義了一個常量ARRAY_SIZE表示需要讀取的數(shù)據(jù)的數(shù)量。然后,使用一個循環(huán)讀取20次數(shù)據(jù),并將它們存儲到一個數(shù)組中。接著,用希爾排序算法對數(shù)組進行排序。在排序完成后,計算數(shù)組中除去最大值和最小值的元素之和,并計算平均值。最后,返回計算得到的平均值。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 傳感器
    +關(guān)注

    關(guān)注

    2541

    文章

    49961

    瀏覽量

    747515
  • 單片機
    +關(guān)注

    關(guān)注

    6023

    文章

    44376

    瀏覽量

    628400
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    6715

    瀏覽量

    88311
  • 物聯(lián)網(wǎng)
    +關(guān)注

    關(guān)注

    2894

    文章

    43313

    瀏覽量

    366440
  • STM32
    +關(guān)注

    關(guān)注

    2258

    文章

    10828

    瀏覽量

    352490
收藏 人收藏

    評論

    相關(guān)推薦

    FPGA排序-冒泡排序介紹

    排序算法是圖像處理中經(jīng)常使用一種算法,常見的排序算法有插入排序、希爾排序、選擇排序冒泡
    發(fā)表于 07-17 10:12 ?963次閱讀
    FPGA<b class='flag-5'>排序</b>-<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>介紹

    labview 版的冒泡排序

    labview 版的冒泡排序,只是想用Labview表達冒泡法的思想,
    發(fā)表于 06-05 11:18

    冒泡排序

    package algorithms// 冒泡排序// 冒泡排序算法的運作如下:// 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。// 對每一對相鄰元素作同樣的工作,從開始第
    發(fā)表于 10-17 19:03

    常用排序法之一 ——冒泡排序法和選擇排序

    的就是,每一次循環(huán)過程中,通過比較選擇出你需要的**最**。選擇排序法的過程是,通**過比較,選擇出每一輪中最元素,然后把他和這一輪中最最前面的元素交換**,所以這個算法關(guān)鍵是要記
    發(fā)表于 11-01 12:25

    嵌入式stm32實用的排序算法 - 交換排序

    Ⅰ、寫在前面前面寫了關(guān)于ADC采集電壓的文章,大家除了求平均的方式來處理采樣,還有沒有使用到其他的方式來處理采集呢?在某些情況下就需要對一組數(shù)據(jù)
    發(fā)表于 04-12 13:14

    Java冒泡排序的原理是什么?

    Java冒泡排序的原理
    發(fā)表于 11-06 07:12

    冒泡排序法的具體實現(xiàn)方法是什么?

    什么是冒泡排序?冒泡排序法的具體實現(xiàn)方法是什么?
    發(fā)表于 07-15 06:48

    基于STM32單片機水質(zhì)檢測PH檢測采集傳感器模塊設(shè)計資料分享

    系統(tǒng)功能設(shè)計(末尾附文件)本系統(tǒng)由STM32單片機核心板、超聲波測距模塊、PH傳感器模塊、電導率傳感器、LCD1602液晶及電源組成。1、超聲波
    發(fā)表于 02-21 06:01

    一文了解冒泡排序

    冒泡排序是一種交換排序。 什么是交換排序呢? 交換排序:兩兩比較待排序的關(guān)鍵字,并交
    的頭像 發(fā)表于 01-17 12:47 ?2969次閱讀
    一文了解<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>

    揭秘冒泡排序、交換排序和插入排序

    01 — 冒泡排序 在實現(xiàn)冒泡排序代碼之前我們先理解一下什么是冒泡排序,我們舉一個現(xiàn)實生活中的例
    的頭像 發(fā)表于 06-18 09:57 ?1466次閱讀

    C語言冒泡排序工程代碼匯總

    C語言冒泡排序工程代碼匯總
    發(fā)表于 08-30 11:06 ?3次下載

    冒泡排序的基本思想

    冒泡排序的英文Bubble Sort,是一種最基礎(chǔ)的交換排序。之所以叫做冒泡排序,因為每一個元素都可以像小氣泡一樣,根據(jù)自身大小一點一點向數(shù)
    的頭像 發(fā)表于 01-20 11:38 ?5648次閱讀
    <b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>的基本思想

    php版冒泡排序是如何實現(xiàn)的?

    無論學習哪一種編程語言,進行算法方面的訓練時都繞不開“排序”。排序在進階編程中有非常廣泛的應(yīng)用,要想成為編程高手,排序算法是必須要掌握的。而冒泡排序
    的頭像 發(fā)表于 01-20 10:39 ?808次閱讀
    php版<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>是如何實現(xiàn)的?

    怎樣運用Java實現(xiàn)冒泡排序和Arrays排序出來

    數(shù)據(jù)結(jié)構(gòu)中我們學習了解了冒泡排序和Arrays排序的基本算法,但沒能夠用編程語言實現(xiàn)出來。那我們應(yīng)該怎樣運用Java通過編程語言將
    的頭像 發(fā)表于 03-02 09:37 ?428次閱讀
    怎樣運用Java實現(xiàn)<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>和Arrays<b class='flag-5'>排序</b>出來

    jwt冒泡排序的原理

    jwt簡介 冒泡排序: (Bubble Sort)是一種簡單的交換排序。之所以叫做冒泡排序,因為我們可以把每個元素當成一個小氣泡,根據(jù)氣泡大
    的頭像 發(fā)表于 09-25 16:33 ?451次閱讀
    jwt<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>的原理