一、前言
在物聯(lián)網(wǎng)、單片機(jī)開發(fā)中,經(jīng)常需要采集各種傳感器的數(shù)據(jù)。比如:溫度、濕度、MQ2、MQ3、MQ4等等傳感器數(shù)據(jù)。這些數(shù)據(jù)采集過程中可能有波動(dòng),偶爾不穩(wěn)定,為了得到穩(wěn)定的值,我們可以對(duì)數(shù)據(jù)多次采集,進(jìn)行排序,去掉最大和最小的值,然后取平均值返回。
二、排序算法
【1】冒泡排序
冒泡排序(Bubble Sort)是一種簡(jiǎn)單的排序算法,也是最基礎(chǔ)、最容易理解的一種排序算法。它會(huì)遍歷要排序的數(shù)組,依次比較相鄰兩個(gè)元素的大小,如果前一個(gè)元素比后一個(gè)元素大,就交換這兩個(gè)元素的位置。
冒泡排序的過程如下:
- 從數(shù)組的第一個(gè)元素開始,依次比較相鄰的兩個(gè)元素,如果前一個(gè)元素比后一個(gè)元素大,則交換這兩個(gè)元素的位置。
- 繼續(xù)比較相鄰的元素,直到數(shù)組的最后一個(gè)元素。
- 重復(fù)執(zhí)行步驟1和步驟2,直到整個(gè)數(shù)組都按照從小到大的順序排列好。
冒泡排序的時(shí)間復(fù)雜度是O(N^2),其中N是數(shù)組中元素的數(shù)量。在實(shí)際應(yīng)用中,由于其時(shí)間復(fù)雜度較高,冒泡排序很少被用于大規(guī)模數(shù)據(jù)的排序,但它仍然是一種優(yōu)秀的教學(xué)工具,因?yàn)樗菀桌斫夂蛯?shí)現(xiàn),并且可以幫助初學(xué)者理解排序算法的基本思想。
以下是C語(yǔ)言代碼的實(shí)現(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;
}
}
}
}
?
// 計(jì)算平均值函數(shù),去除最大值和最小值
int calculateAverage() {
int arr[ARRAY_SIZE];
// 連續(xù)讀取20次數(shù)據(jù)
for(int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = ReadADC();
}
// 對(duì)數(shù)組進(jìn)行排序
bubbleSort(arr, ARRAY_SIZE);
// 去掉最大值和最小值
int sum = 0;
for(int i = 1; i < ARRAY_SIZE-1; i++) {
sum += arr[i];
}
// 計(jì)算平均值并返回
return sum / (ARRAY_SIZE-2);
}
在函數(shù)中,首先定義了一個(gè)常量ARRAY_SIZE
表示需要讀取的數(shù)據(jù)的數(shù)量。然后,使用一個(gè)循環(huán)讀取20次數(shù)據(jù),并將它們存儲(chǔ)到一個(gè)數(shù)組中。接著,用冒泡排序算法對(duì)數(shù)組進(jìn)行排序。在排序完成后,計(jì)算數(shù)組中除去最大值和最小值的元素之和,并計(jì)算平均值。最后,返回計(jì)算得到的平均值。
【2】插入排序
插入排序(Insertion Sort)是一種簡(jiǎn)單直觀的排序算法,它的基本思想是將一個(gè)元素插入到已排序好的序列中的適當(dāng)位置,使得插入后仍然有序。
插入排序的過程如下:
- 假設(shè)第一個(gè)元素已經(jīng)是排好序的序列,從第二個(gè)元素開始,依次將每個(gè)元素插入到已經(jīng)排好序的序列中。
- 每次從未排序的部分中取出一個(gè)元素,與已排序的序列中的元素從后向前依次比較,找到插入的位置,即找到一個(gè)比當(dāng)前元素小的值或者已經(jīng)到了開頭位置。
- 將當(dāng)前元素插入到已排序序列的合適位置上,重新調(diào)整已排序的序列,繼續(xù)對(duì)未排序的序列進(jìn)行排序。
- 重復(fù)執(zhí)行步驟2和步驟3,直到整個(gè)數(shù)組都按照從小到大的順序排列好。
插入排序的時(shí)間復(fù)雜度是O(N^2),其中N是數(shù)組中元素的數(shù)量。在實(shí)際應(yīng)用中,插入排序通常適用于處理小規(guī)模數(shù)據(jù)或者已經(jīng)接近有序的數(shù)據(jù),因?yàn)榇藭r(shí)插入排序的效率高于其他排序算法。
以下是C語(yǔ)言代碼的實(shí)現(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;
}
}
?
// 計(jì)算平均值函數(shù),去除最大值和最小值
int calculateAverage() {
int arr[ARRAY_SIZE];
// 連續(xù)讀取20次數(shù)據(jù)
for(int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = ReadADC();
}
// 對(duì)數(shù)組進(jìn)行排序
insertionSort(arr, ARRAY_SIZE);
// 去掉最大值和最小值
int sum = 0;
for(int i = 1; i < ARRAY_SIZE-1; i++) {
sum += arr[i];
}
// 計(jì)算平均值并返回
return sum / (ARRAY_SIZE-2);
}
在函數(shù)中,首先定義了一個(gè)常量ARRAY_SIZE
表示需要讀取的數(shù)據(jù)的數(shù)量。然后,使用一個(gè)循環(huán)讀取20次數(shù)據(jù),并將它們存儲(chǔ)到一個(gè)數(shù)組中。接著,用插入排序算法對(duì)數(shù)組進(jìn)行排序。在排序完成后,計(jì)算數(shù)組中除去最大值和最小值的元素之和,并計(jì)算平均值。最后,返回計(jì)算得到的平均值。
【3】希爾排序
希爾排序(Shell Sort)是一種由Donald Shell在1959年發(fā)明的排序算法,它是插入排序的一種變體,旨在減少排序中元素的移動(dòng)次數(shù),從而使算法更快。希爾排序的基本思想是把數(shù)組中相距某個(gè)“增量”的元素組成一個(gè)子序列,對(duì)每個(gè)子序列進(jìn)行插入排序,然后逐步縮小增量,重復(fù)進(jìn)行上述操作,直到增量為1,最后再對(duì)整個(gè)數(shù)組進(jìn)行一次插入排序。
希爾排序的過程如下:
- 選擇一個(gè)增量序列,將待排序的數(shù)組按照這個(gè)增量序列分成若干組(子序列)。通常,在第一次排序時(shí),增量取數(shù)組長(zhǎng)度的一半,以后每次將增量減半,直到增量為1。
- 對(duì)每個(gè)子序列進(jìn)行插入排序,即將每個(gè)子序列中的元素按照遞增的順序插入到已排序好的序列中。
- 重復(fù)執(zhí)行步驟2,改變?cè)隽浚钡皆隽繛?。
- 最后再對(duì)整個(gè)數(shù)組進(jìn)行插入排序。
希爾排序的時(shí)間復(fù)雜度與所選取的增量序列有關(guān)。最壞情況下的時(shí)間復(fù)雜度為O(N^2),其中N是數(shù)組中元素的數(shù)量。但在大多數(shù)情況下,希爾排序的時(shí)間復(fù)雜度優(yōu)于O(N^2),可以達(dá)到O(N log N)的級(jí)別。希爾排序的空間復(fù)雜度為O(1),因?yàn)樗谂判蜻^程中只需要常數(shù)個(gè)額外的存儲(chǔ)空間。
以下是C語(yǔ)言代碼實(shí)現(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;
}
}
}
?
// 計(jì)算平均值函數(shù),去除最大值和最小值
int calculateAverage() {
int arr[ARRAY_SIZE];
// 連續(xù)讀取20次數(shù)據(jù)
for(int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = ReadADC();
}
// 對(duì)數(shù)組進(jìn)行排序
shellSort(arr, ARRAY_SIZE);
// 去掉最大值和最小值
int sum = 0;
for(int i = 1; i < ARRAY_SIZE-1; i++) {
sum += arr[i];
}
// 計(jì)算平均值并返回
return sum / (ARRAY_SIZE-2);
}
在函數(shù)中,首先定義了一個(gè)常量ARRAY_SIZE
表示需要讀取的數(shù)據(jù)的數(shù)量。然后,使用一個(gè)循環(huán)讀取20次數(shù)據(jù),并將它們存儲(chǔ)到一個(gè)數(shù)組中。接著,用希爾排序算法對(duì)數(shù)組進(jìn)行排序。在排序完成后,計(jì)算數(shù)組中除去最大值和最小值的元素之和,并計(jì)算平均值。最后,返回計(jì)算得到的平均值。
審核編輯:湯梓紅
-
傳感器
+關(guān)注
關(guān)注
2553文章
51407瀏覽量
756638 -
單片機(jī)
+關(guān)注
關(guān)注
6043文章
44621瀏覽量
638616 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7145瀏覽量
89585 -
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2914文章
44939瀏覽量
377084 -
STM32
+關(guān)注
關(guān)注
2272文章
10924瀏覽量
357599
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論