欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++中四種常用查找算法的實(shí)現(xiàn)

 更新時(shí)間:2023年11月29日 11:36:08   作者:微軟技術(shù)分享  
C語言作為一種強(qiáng)大的編程語言,提供了多種搜索算法的實(shí)現(xiàn)方式,本文將介紹C語言中的四種常見搜索算法并提供每種算法的簡(jiǎn)單實(shí)現(xiàn)示例,需要的小伙伴可以參考下

在計(jì)算機(jī)科學(xué)中,搜索算法是一種用于在數(shù)據(jù)集合中查找特定元素的算法。C語言作為一種強(qiáng)大的編程語言,提供了多種搜索算法的實(shí)現(xiàn)方式。本文將介紹C語言中的四種常見搜索算法其中包括(線性查找,二分法查找,樹結(jié)構(gòu)查找,分塊查找),并提供每種算法的簡(jiǎn)單實(shí)現(xiàn)示例。

常見的查找算法主要有以下幾種:

線性查找(Linear Search):

  • 簡(jiǎn)單直觀,適用于無序列表。
  • 從列表的一端開始逐個(gè)元素比較,直到找到目標(biāo)元素或遍歷完整個(gè)列表。

二分查找(Binary Search):

  • 適用于有序列表。
  • 每次將目標(biāo)值與中間元素比較,可以迅速縮小搜索范圍。

樹結(jié)構(gòu)查找(樹的各種形式,如二叉搜索樹、AVL樹、紅黑樹等):

  • 通過樹結(jié)構(gòu),可以更加高效地進(jìn)行查找、插入和刪除操作。
  • 二叉搜索樹要求左子樹上所有結(jié)點(diǎn)的值小于根結(jié)點(diǎn)的值,右子樹上所有結(jié)點(diǎn)的值大于根結(jié)點(diǎn)的值。

分塊查找(Block Search):

  • 將數(shù)據(jù)分成若干塊,每一塊中的元素?zé)o序,但塊與塊之間有序。
  • 先確定目標(biāo)元素所在的塊,再在塊內(nèi)進(jìn)行線性查找。

這些查找算法各自有適用的場(chǎng)景和優(yōu)勢(shì),選擇合適的查找算法取決于數(shù)據(jù)的特性以及實(shí)際應(yīng)用的需求。

線性查找(Linear Search)

線性搜索,又稱為順序搜索(Sequential Search),是一種簡(jiǎn)單直觀的查找算法。該算法通過順序遍歷數(shù)據(jù)集,逐一比較每個(gè)元素與目標(biāo)值是否相等,直到找到目標(biāo)值或遍歷完整個(gè)數(shù)據(jù)集。

算法步驟

  • 從頭到尾遍歷數(shù)據(jù)集: 從數(shù)據(jù)集的第一個(gè)元素開始,依次比較每個(gè)元素與目標(biāo)值是否相等。
  • 比較目標(biāo)值: 對(duì)于每個(gè)元素,與目標(biāo)值進(jìn)行比較。
  • 找到目標(biāo)值: 如果找到了與目標(biāo)值相等的元素,返回該元素的位置或索引。
  • 遍歷完整個(gè)數(shù)據(jù)集: 如果遍歷完整個(gè)數(shù)據(jù)集仍未找到目標(biāo)值,返回未找到的標(biāo)記(通常是一個(gè)特殊值,如-1)。

特點(diǎn)

  • 適用于小型數(shù)據(jù)集: 線性搜索適用于小型數(shù)據(jù)集,對(duì)于大型數(shù)據(jù)集可能效率較低。
  • 無序數(shù)據(jù): 不依賴數(shù)據(jù)的排列順序,適用于無序數(shù)據(jù)。
  • 簡(jiǎn)單直觀: 實(shí)現(xiàn)簡(jiǎn)單,易于理解。

線性搜索是最簡(jiǎn)單的搜索算法之一,它按順序遍歷數(shù)據(jù)集合,查找目標(biāo)元素。以下是一個(gè)線性搜索的C語言示例:

#include <stdio.h>

int linearSearch(int arr[], int n, int target)
{
    for (int i = 0; i < n; i++)
    {
        if (arr[i] == target)
        {
            return i; // 找到則返回索引
        }
    }
    return -1; // 未找到則返回-1
}

int main(int argc, char *argv[])
{
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 3;
    int result = linearSearch(arr, n, target);
    if (result != -1)
    {
        printf("元素在索引 %d 處找到\n", result);
    } else
    {
        printf("未找到元素\n");
    }
    return 0;
}

二分查找(Binary Search)

二分搜索(Binary Search)是一種在有序數(shù)組中查找目標(biāo)值的算法。它通過反復(fù)將查找范圍劃分為兩半并比較目標(biāo)值與中間元素的大小,從而縮小搜索范圍,直到找到目標(biāo)值或確定目標(biāo)值不存在。

算法步驟

初始化: 確定搜索范圍的起始點(diǎn) left 和終止點(diǎn) right

循環(huán)條件: 當(dāng) left 小于等于 right 時(shí)執(zhí)行循環(huán)。

計(jì)算中間位置: 計(jì)算中間位置 midmid = (left + right) / 2。

比較目標(biāo)值: 將目標(biāo)值與中間元素進(jìn)行比較。

  • 如果目標(biāo)值等于中間元素,找到目標(biāo),返回索引。
  • 如果目標(biāo)值小于中間元素,說明目標(biāo)值在左半部分,更新 right = mid - 1。
  • 如果目標(biāo)值大于中間元素,說明目標(biāo)值在右半部分,更新 left = mid + 1。

循環(huán)結(jié)束: 當(dāng) left 大于 right,表示搜索范圍為空,未找到目標(biāo)值。

特點(diǎn)

  • 有序數(shù)組: 二分搜索要求數(shù)組是有序的,以便通過比較中間元素確定目標(biāo)值在哪一半。
  • 高效性: 由于每一步都將搜索范圍縮小一半,因此二分搜索的平均時(shí)間復(fù)雜度為 O(log n)。
  • 適用性: 適用于靜態(tài)數(shù)據(jù)集或很少變化的數(shù)據(jù)集,不適用于頻繁插入、刪除操作的動(dòng)態(tài)數(shù)據(jù)集。

二分搜索要求數(shù)據(jù)集合是有序的,以下是一個(gè)二分搜索的C語言示例:

#include <stdio.h>

int binary_search(int key, int a[], int n)
{
  int low, high, mid, count = 0, count1 = 0;
  low = 0;
  high = n - 1;
  while (low<high)
  {
    count++;                    // 記錄查找次數(shù)
    mid = (low + high) / 2;     // 求出中間位置
    if (key<a[mid])             // 當(dāng)key小于中間值
      high = mid - 1;         // 確定左子表范圍
    else if (key>a[mid])        // 當(dāng)key大于中間值
      low = mid + 1;          // 確定右子表范圍
    else if (key == a[mid])     // 當(dāng)key等于中間值證明查找成功
    {
      printf("查找元素: %d Array[%d]=%d\n", count, mid, key);
      count1++;            //count1記錄查找成功次數(shù)
      break;
    }
  }
  if (count1 == 0)
    return 0;
}

int main(int argc, char *argv[])
{
  int number = 10, key = 6;
  int Array[10] = { 1, 5, 6, 7, 9, 3, 4, 6, 0, 2 };

  binary_search(key, Array, number);

  return 0;
}

二叉搜索樹 (BST)

二叉搜索樹(Binary Search Tree,BST)是一種二叉樹數(shù)據(jù)結(jié)構(gòu),其中每個(gè)節(jié)點(diǎn)都有一個(gè)鍵值,且滿足以下性質(zhì):

  • 對(duì)于樹中的每個(gè)節(jié)點(diǎn),其左子樹中的所有節(jié)點(diǎn)的鍵值都小于該節(jié)點(diǎn)的鍵值。
  • 對(duì)于樹中的每個(gè)節(jié)點(diǎn),其右子樹中的所有節(jié)點(diǎn)的鍵值都大于該節(jié)點(diǎn)的鍵值。
  • 左、右子樹也分別為二叉搜索樹。

這個(gè)性質(zhì)使得在二叉搜索樹中可以高效地進(jìn)行搜索、插入和刪除操作。

特點(diǎn)

有序性: 由于BST的定義,其中的元素是有序排列的。對(duì)于任意節(jié)點(diǎn),其左子樹的值小于該節(jié)點(diǎn),右子樹的值大于該節(jié)點(diǎn),因此通過中序遍歷BST可以得到有序的元素序列。

高效的搜索操作: 由于有序性,可以通過比較鍵值快速定位目標(biāo)節(jié)點(diǎn),使搜索操作的平均時(shí)間復(fù)雜度為 O(log n)。在最壞情況下(樹退化為鏈表),搜索的時(shí)間復(fù)雜度為 O(n)。

高效的插入和刪除操作: 插入和刪除操作也涉及到比較鍵值和調(diào)整樹的結(jié)構(gòu),平均情況下的時(shí)間復(fù)雜度為 O(log n)。在最壞情況下,樹可能變得不平衡,導(dǎo)致時(shí)間復(fù)雜度為 O(n),但通過平衡二叉搜索樹(如 AVL 樹、紅黑樹等)可以保持樹的平衡。

操作

搜索(Search): 從根節(jié)點(diǎn)開始比較目標(biāo)值,根據(jù)比較結(jié)果選擇左子樹或右子樹,直到找到目標(biāo)節(jié)點(diǎn)或達(dá)到葉子節(jié)點(diǎn)。

插入(Insert): 從根節(jié)點(diǎn)開始,按照比較結(jié)果選擇左子樹或右子樹,直到找到合適的插入位置,插入新節(jié)點(diǎn)。

刪除(Delete): 找到要?jiǎng)h除的節(jié)點(diǎn),可能有以下幾種情況:

  • 若該節(jié)點(diǎn)為葉子節(jié)點(diǎn),直接刪除。
  • 若該節(jié)點(diǎn)有一個(gè)子節(jié)點(diǎn),用子節(jié)點(diǎn)替代該節(jié)點(diǎn)。
  • 若該節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn),找到右子樹中的最小節(jié)點(diǎn)或左子樹中的最大節(jié)點(diǎn),替代該節(jié)點(diǎn),并遞歸刪除被替代的節(jié)點(diǎn)。

以下是一個(gè)簡(jiǎn)化的BST的C語言示例:

#include <stdio.h>
#include <stdlib.h>

struct Node
{
    int key;
    struct Node *left, *right;
};

struct Node* newNode(int key)
{
    struct Node* node = (struct Node*)malloc(sizeof(struct Node));
    node->key = key;
    node->left = node->right = NULL;
    return node;
}

struct Node* insert(struct Node* root, int key)
{
    if (root == NULL)
        return newNode(key);
    if (key < root->key)
        root->left = insert(root->left, key);
    else if (key > root->key)
        root->right = insert(root->right, key);
    return root;
}

int main(int argc, char *argv[])
{
    struct Node* root = NULL;
    int keys[] = {3, 1, 5, 2, 4};
    for (int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++)
    {
        root = insert(root, keys[i]);
    }
    // 可以在 'root' 上執(zhí)行BST操作
    return 0;
}

分塊查找(Block Search)

分塊搜索(Block Search)是一種在查找大量數(shù)據(jù)中的目標(biāo)值時(shí),將數(shù)據(jù)分成若干塊,然后在塊內(nèi)進(jìn)行查找的策略。這種方法適用于一些動(dòng)態(tài)更新頻繁,但每次更新數(shù)據(jù)量較小的場(chǎng)景。

算法步驟

數(shù)據(jù)分塊: 將大量數(shù)據(jù)按照一定的規(guī)則分成若干塊。

建立索引表: 對(duì)每個(gè)塊建立索引,記錄每塊的起始位置、結(jié)束位置和關(guān)鍵字(通常是塊內(nèi)最大的關(guān)鍵字)。

查找塊: 根據(jù)目標(biāo)值的大小確定它可能在哪個(gè)塊中,找到相應(yīng)的塊。

在塊內(nèi)查找: 在確定的塊內(nèi)使用線性查找或其他查找算法尋找目標(biāo)值。

特點(diǎn)

  • 適用于動(dòng)態(tài)數(shù)據(jù): 分塊搜索適用于數(shù)據(jù)集動(dòng)態(tài)更新的情況,因?yàn)槊看胃聰?shù)據(jù)只需更新相應(yīng)塊的索引。
  • 索引表: 建立索引表有助于快速定位目標(biāo)值可能存在的塊,提高查找效率。
  • 非均勻分塊: 可以根據(jù)數(shù)據(jù)的特點(diǎn)進(jìn)行非均勻分塊,以適應(yīng)不同數(shù)據(jù)分布情況。

該查找與二分查找類似,都是對(duì)半分,分塊則可以分為多塊,效率更高一些。如下這段C語言代碼實(shí)現(xiàn)了分塊查找算法。分塊查找是一種基于塊的數(shù)據(jù)結(jié)構(gòu)的搜索算法,通過將數(shù)據(jù)集劃分為若干塊(或稱為塊),并為每個(gè)塊建立一個(gè)索引。每個(gè)索引記錄了該塊的起始位置、結(jié)束位置以及該塊內(nèi)元素的最大值。

#include <stdio.h>

struct index           //定義塊的結(jié)構(gòu)
{
  int key;
  int start;
  int end;
}index_table[4];       //定義結(jié)構(gòu)體數(shù)組

int block_search(int key, int a[])          //自定義實(shí)現(xiàn)分塊查找
{
  int i, j;
  i = 1;
  while (i <= 3 && key>index_table[i].key)      //確定在哪個(gè)塊中
    i++;
  if (i>3)                                  //大于分得的塊數(shù),則返回0
    return 0;
  j = index_table[i].start;                  //j等于塊范圍的起始值
  while (j <= index_table[i].end&&a[j] != key)  //在確定的塊內(nèi)進(jìn)行查找
    j++;
  if (j>index_table[i].end)    //如果大于塊范圍的結(jié)束值,則說明沒有要查找的數(shù)
    j = 0;
  return j;
}

int main(int argc, char *argv[])
{
  int x, y = 0,ref = 0;
  int key = 8;
  int Array[16] = { 1, 3, 4, 5, 6, 7, 8, 9, 0, 4, 3, 5, 6, 7, 8, 9 };

  for (x = 1; x <= 3; x++)
  {
    index_table[x].start = y + 1;       // 確定每個(gè)范圍的起始行
    y = y + 1;
    index_table[x].end = y + 4;         // 確定每個(gè)塊范圍的結(jié)束值
    y = y + 4;
    index_table[x].key = Array[y];      // 確定每個(gè)塊范圍中元素的最大值
  }

  ref = block_search(key, Array);
  if (ref != 0)
  {
    printf("position is: %d \n", ref);
  }
  return 0;
}

以上就是C/C++中四種常用查找算法的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于C++查找算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言判斷字符串長度的方法小結(jié)

    C語言判斷字符串長度的方法小結(jié)

    學(xué)過C/C++的人都知道,在C/C++中并沒有提供直接獲取數(shù)組長度的函數(shù),對(duì)于存放字符串的字符數(shù)組提供了一個(gè)strlen函數(shù)獲取其長度,那么對(duì)于其他類型的數(shù)組如何獲取他們的長度呢?本文給大家介紹了C語言判斷字符串長度的方法小結(jié),需要的朋友可以參考下
    2024-08-08
  • C++11中的引用限定符示例代碼

    C++11中的引用限定符示例代碼

    C++中有左值和右值的概念,其實(shí),左值和右值的區(qū)分也同樣適用于類對(duì)象,本文中將左值的類對(duì)象稱為左值對(duì)象,將右值的類對(duì)象稱為右值對(duì)象,對(duì)C++11?引用限定符相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • C++基本算法思想之窮舉法

    C++基本算法思想之窮舉法

    在使用窮舉法時(shí),需要明確問題的答案的范圍,這樣才可以在指定的范圍內(nèi)搜索答案。指定范圍之后,就可以使用循環(huán)語句和條件語句逐步驗(yàn)證候選答案的正確性,從而得到需要的正確答案
    2013-10-10
  • 用C/C++代碼檢測(cè)ip能否ping通(配合awk和system可以做到批量檢測(cè))

    用C/C++代碼檢測(cè)ip能否ping通(配合awk和system可以做到批量檢測(cè))

    今天小編就為大家分享一篇關(guān)于用C/C++代碼檢測(cè)ip能否ping通(配合awk和system可以做到批量檢測(cè)),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • CRITICAL_SECTION用法案例詳解

    CRITICAL_SECTION用法案例詳解

    這篇文章主要介紹了CRITICAL_SECTION用法案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 數(shù)據(jù)結(jié)構(gòu)C語言鏈表的實(shí)現(xiàn)介紹

    數(shù)據(jù)結(jié)構(gòu)C語言鏈表的實(shí)現(xiàn)介紹

    大家好,本篇文章主要講的是數(shù)據(jù)結(jié)構(gòu)C語言鏈表的實(shí)現(xiàn)介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2021-12-12
  • C++語言設(shè)計(jì)實(shí)現(xiàn)五子棋

    C++語言設(shè)計(jì)實(shí)現(xiàn)五子棋

    這篇文章主要為大家詳細(xì)介紹了C++語言設(shè)計(jì)實(shí)現(xiàn)五子棋,包括數(shù)據(jù)結(jié)構(gòu)和對(duì)象設(shè)計(jì)及主函數(shù)調(diào)用實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • C++ 中繼承與動(dòng)態(tài)內(nèi)存分配的詳解

    C++ 中繼承與動(dòng)態(tài)內(nèi)存分配的詳解

    這篇文章主要介紹了C++ 中繼承與動(dòng)態(tài)內(nèi)存分配的詳解的相關(guān)資料,這里提供實(shí)例幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • c++禁止函數(shù)的傳值調(diào)用的方法

    c++禁止函數(shù)的傳值調(diào)用的方法

    這篇文章主要介紹了c++禁止函數(shù)的傳值調(diào)用的方法,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • 詳解C/C++中new?A與new?A()的區(qū)別

    詳解C/C++中new?A與new?A()的區(qū)別

    這篇文章主要通過一些簡(jiǎn)單的示例為大家詳細(xì)介紹一下C/C++中new?A與new?A()的區(qū)別,文中的示例代碼簡(jiǎn)潔易懂,快跟隨小編一起學(xué)習(xí)起來吧
    2023-07-07

最新評(píng)論