五種常見的搜索算法在C語言環(huán)境中的應用及解析
一、線性搜索(Linear Search)
線性搜索是最基礎的查找算法,適用于對未排序或無特定結(jié)構(gòu)的數(shù)據(jù)集合進行搜索。在C語言中實現(xiàn)時,線性搜索通過遍歷數(shù)組或鏈表中的每一個元素,并與目標值進行比較,直至找到匹配項或者遍歷完所有元素。其時間復雜度為O(n),其中n代表數(shù)據(jù)集的大小。
#include <stdbool.h> // 引入bool類型
// 定義線性搜索函數(shù),返回值為找到元素的位置(下標),未找到則返回-1
int linear_search(const int array[], const int size, const int target) {
for (int i = 0; i < size; ++i) {
if (array[i] == target) {
return i;
}
}
return -1;
}
// 示例主函數(shù)
int main(void) {
const int input_array[] = {1, 3, 5, 7, 9};
const int search_target = 5;
// 調(diào)用線性搜索函數(shù)
int index = linear_search(input_array, sizeof(input_array) / sizeof(input_array[0]), search_target);
if (index != -1) {
printf("Element found at index: %d\n", index);
} else {
printf("Element not found in the array.\n");
}
return 0;
}
二、二分搜索(Binary Search)
二分搜索是一種高效的搜索算法,要求數(shù)據(jù)集事先已排序。它通過不斷將搜索范圍減半來快速定位目標值。對于長度為n的有序數(shù)組,二分搜索的時間復雜度為O(log n)。
#include <stdbool.h> // 引入bool類型
// 二分搜索函數(shù),輸入?yún)?shù)為已排序數(shù)組、數(shù)組大小和目標值,返回值為目標值在數(shù)組中的索引(如果存在),否則返回-1表示未找到
int binary_search(const int array[], const int size, const int target) {
int left = 0;
int right = (size - 1);
while (left <= right) {
int mid = (left + right) / 2;
if (array[mid] == target) {
return mid;
} else if (array[mid] < target) {
left = mid + 1;
} else { // array[mid] > target
right = mid - 1;
}
}
return -1; // 目標值不在數(shù)組中
}
// 示例主函數(shù)
int main(void) {
const int input_array[] = {1, 3, 5, 7, 9};
const int search_target = 5;
// 檢查輸入數(shù)組是否已排序
for (int i = 1; i < sizeof(input_array) / sizeof(input_array[0]); ++i) {
assert(input_array[i] >= input_array[i - 1]);
}
// 調(diào)用二分搜索函數(shù)
int index = binary_search(input_array, sizeof(input_array) / sizeof(input_array[0]), search_target);
if (index != -1) {
printf("Element found at index: %d\n", index);
} else {
printf("Element not found in the array.\n");
}
return 0;
}
// 注意:在實際嵌入式開發(fā)中,assert()宏可能不被推薦使用,此處僅用于演示目的。
三、哈希表搜索(Hash Table Search)
哈希表是一種通過哈希函數(shù)將鍵轉(zhuǎn)化為索引,從而實現(xiàn)高效查找的數(shù)據(jù)結(jié)構(gòu)。理想情況下,哈希表能在常數(shù)時間內(nèi)完成查找操作。在C語言中,可以使用數(shù)組和指針構(gòu)建簡單哈希表。
#include <stdbool.h> // 引入bool類型
// 假設我們使用一個固定大小的哈希表,這里以16為例
#define HASH_TABLE_SIZE 16
typedef struct {
int key;
int value;
} HashEntry;
// 初始化哈希表為全空標志
HashEntry hash_table[HASH_TABLE_SIZE] = {0};
// 簡單哈希函數(shù)示例,實際應用中可能需要更復雜的哈希函數(shù)減少沖突
int simple_hash(int key) {
return key % HASH_TABLE_SIZE;
}
// 插入數(shù)據(jù)到哈希表,如果存在沖突則進行線性探測
void hash_table_insert(int key, int value) {
int index = simple_hash(key);
while (hash_table[index].key != 0 && hash_table[index].key != key) {
index = (index + 1) % HASH_TABLE_SIZE; // 探測下一個槽位
}
hash_table[index].key = key;
hash_table[index].value = value;
}
// 在哈希表中查找鍵值對,返回true表示找到,false表示未找到
bool hash_table_search(const int target_key, int *found_value) {
int index = simple_hash(target_key);
while (hash_table[index].key != 0) {
if (hash_table[index].key == target_key) {
*found_value = hash_table[index].value;
return true;
}
index = (index + 1) % HASH_TABLE_SIZE; // 探測下一個槽位
}
return false;
}
// 示例主函數(shù)
int main(void) {
hash_table_insert(3, "apple");
hash_table_insert(7, "banana");
int found_value;
bool is_found = hash_table_search(7, &found_value);
if (is_found) {
printf("Element found: %d\n", found_value); // 在實際嵌入式開發(fā)中,應替換為合適的輸出方式
} else {
printf("Element not found in the hash table.\n"); // 同樣應替換為合適的方式
}
return 0;
}
四、位圖搜索(Bitmap Search)
位圖搜索主要用于標識大量整數(shù)值是否存在的一種方法,特別適合于空間有限且整數(shù)分布范圍相對較小的情況。在C語言中,位圖通常表現(xiàn)為一個字節(jié)數(shù)組,每個比特位對應一個可能的狀態(tài)。
#include <stdbool.h>
// 假設最大支持的標記數(shù)量為MAX_MARKS
#define MAX_MARKS 32
// 定義位圖結(jié)構(gòu)體
typedef struct {
unsigned int bitmap[MAX_MARKS / (sizeof(unsigned int) * 8)]; // 按照單片機平臺上的整型寬度來確定數(shù)組大小
} Bitmap;
// 初始化位圖
void bitmap_init(Bitmap *bmp) {
for (unsigned int i = 0; i < sizeof(bmp->bitmap) / sizeof(bmp->bitmap[0]); ++i) {
bmp->bitmap[i] = 0;
}
}
// 設置位圖中指定位置的標志位
void bitmap_set(Bitmap *bmp, int mark) {
assert(mark >= 0 && mark < MAX_MARKS); // MISRA C要求:確保輸入值有效
bmp->bitmap[mark / (sizeof(unsigned int) * 8)] |= (1 << (mark % (sizeof(unsigned int) * 8)));
}
// 清除位圖中指定位置的標志位
void bitmap_clear(Bitmap *bmp, int mark) {
assert(mark >= 0 && mark < MAX_MARKS);
bmp->bitmap[mark / (sizeof(unsigned int) * 8)] &= ~(1 << (mark % (sizeof(unsigned int) * 8)));
}
// 查找位圖中是否存在指定位置的標志位
bool bitmap_search(const Bitmap *bmp, int mark) {
assert(mark >= 0 && mark < MAX_MARKS);
return (bmp->bitmap[mark / (sizeof(unsigned int) * 8)] & (1 << (mark % (sizeof(unsigned int) * 8)))) != 0;
}
// 示例主函數(shù)
int main(void) {
Bitmap bmp;
bitmap_init(&bmp);
bitmap_set(&bmp, 5);
bitmap_set(&bmp, 9);
if (bitmap_search(&bmp, 5)) {
printf("Mark 5 is set.\n"); // 在實際嵌入式開發(fā)中,應替換為合適的輸出方式
} else {
printf("Mark 5 is not set.\n");
}
if (bitmap_search(&bmp, 9)) {
printf("Mark 9 is set.\n");
} else {
printf("Mark 9 is not set.\n");
}
return 0;
}
五、有限狀態(tài)機(FSM)搜索
有限狀態(tài)機(FSM)主要用于處理輸入序列并根據(jù)當前狀態(tài)決定下一步行為。在搜索場景下,F(xiàn)SM可用于識別模式、解析語法等任務。在C語言中,可以使用結(jié)構(gòu)體存儲狀態(tài)信息以及狀態(tài)轉(zhuǎn)移函數(shù)指針。文章來源:http://www.zghlxwxcb.cn/news/detail-826024.html
#include <stdbool.h>
// 定義狀態(tài)機的狀態(tài)枚舉
typedef enum {
FSM_STATE_IDLE = 0,
FSM_STATE_PROCESSING,
FSM_STATE_FINISHED,
// ...其他狀態(tài)...
FSM_STATE_COUNT // 用于獲取狀態(tài)總數(shù)
} FSM_State_t;
// 定義事件枚舉
typedef enum {
FSM_EVENT_NONE = 0,
FSM_EVENT_START,
FSM_EVENT_DATA_RECEIVED,
FSM_EVENT_FINISH,
// ...其他事件...
FSM_EVENT_COUNT // 用于獲取事件總數(shù)
} FSM_Event_t;
// 狀態(tài)機結(jié)構(gòu)體
typedef struct {
FSM_State_t current_state;
} FSM_t;
// 狀態(tài)轉(zhuǎn)移函數(shù)指針類型定義
typedef void (*StateTransitionFunction)(FSM_t *fsm, FSM_Event_t event);
// 狀態(tài)轉(zhuǎn)移表
static const StateTransitionFunction state_transition_table[FSM_STATE_COUNT][FSM_EVENT_COUNT] = {
[FSM_STATE_IDLE] = {
[FSM_EVENT_START] = fsm_idle_on_start,
// 其他事件處理函數(shù)...
},
[FSM_STATE_PROCESSING] = {
[FSM_EVENT_DATA_RECEIVED] = fsm_processing_on_data_received,
// 其他事件處理函數(shù)...
},
// 其他狀態(tài)下的事件處理函數(shù)...
};
// 空閑狀態(tài)下接收到開始事件的處理函數(shù)
static void fsm_idle_on_start(FSM_t *fsm, FSM_Event_t event) {
if (event == FSM_EVENT_START) {
fsm->current_state = FSM_STATE_PROCESSING;
// ...其他操作...
}
}
// 處理中的狀態(tài)下接收到數(shù)據(jù)事件的處理函數(shù)
static void fsm_processing_on_data_received(FSM_t *fsm, FSM_Event_t event) {
if (event == FSM_EVENT_DATA_RECEIVED) {
// ...處理數(shù)據(jù)...
}
// 根據(jù)實際情況更新狀態(tài)
}
// 初始化狀態(tài)機
void fsm_init(FSM_t *fsm) {
fsm->current_state = FSM_STATE_IDLE;
}
// 狀態(tài)機主循環(huán),接收并處理事件
void fsm_process_event(FSM_t *fsm, FSM_Event_t event) {
assert(event >= 0 && event < FSM_EVENT_COUNT); // MISRA C要求:確保輸入值有效
assert(fsm != NULL); // 確保指針非空
state_transition_table[fsm->current_state][event](fsm, event);
}
// 示例主函數(shù)
int main(void) {
FSM_t fsm;
fsm_init(&fsm);
// 假設從某個接口接收事件
while (true) {
FSM_Event_t event = get_next_event(); // 獲取下一個事件的函數(shù),此處僅為示例
fsm_process_event(&fsm, event);
}
return 0;
}
總結(jié):不同的搜索算法有各自適用的場景和優(yōu)勢,理解它們的工作原理并在實際項目中合理選擇和應用是提高軟件性能和資源利用率的關(guān)鍵。上述代碼片段僅為簡要示例,在實際開發(fā)過程中需結(jié)合具體需求和約束條件進行詳細設計和優(yōu)化。文章來源地址http://www.zghlxwxcb.cn/news/detail-826024.html
到了這里,關(guān)于汽車零部件軟件開發(fā)常用搜索算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!