淺析折半查找的時間複雜度

一、折半查找的定義

折半查找(二分查找)是一種常用的查找演算法,它要求待查找的數據結構必須是有序的。

其實現過程如下:

int binary_search(int arr[], int left, int right, int target)
{
    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(arr[mid] == target)
            return mid;
        if(arr[mid] < target)
            left = mid + 1;
        else
            right = mid - 1;
    }
    return -1;
}

二、折半查找的時間複雜度與時間複雜度分析

常見的演算法時間複雜度分別有O(1), O(logn), O(n), O(nlogn), O(n²), O(n³)等。

而折半查找的時間複雜度為O(logn),也就是說它屬於時間複雜度比較小的演算法,適用於大數據量的快速查找。

下面從多個方面來詳細闡述折半查找的時間複雜度。

三、折半查找的時間複雜度與數據規模

折半查找的時間複雜度與數據規模有關,具體表現為:

當數據規模n增大時,時間複雜度O(logn)的速度要比O(n)快,因為O(logn)的增長速度是比O(n)慢的。

如下面的示例所示,隨著數據規模的增大,折半查找演算法與普通查找演算法的時間複雜度對比:

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

int search(int arr[], int len, int target)
{
    for(int i = 0; i < len; i++)
    {
        if(arr[i] == target)
            return i;
    }
    return -1;
}

int binary_search(int arr[], int left, int right, int target)
{
    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(arr[mid] == target)
            return mid;
        if(arr[mid] < target)
            left = mid + 1;
        else
            right = mid - 1;
    }
    return -1;
}

int main()
{
    int len = 100000000;
    int* arr = (int*)malloc(len * sizeof(int));
    for(int i = 0; i < len; i++)
        arr[i] = i;
    int target = len - 1;
    clock_t start, end;
    int ret;

    start = clock();
    ret = binary_search(arr, 0, len - 1, target);
    end = clock();
    printf("binary_search: %d, time: %fs\n", ret, (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();
    ret = search(arr, len, target);
    end = clock();
    printf("search: %d, time: %fs\n", ret, (double)(end - start) / CLOCKS_PER_SEC);

    free(arr);
    return 0;
}

當數據規模為100000000時,折半查找演算法的耗時只有0.001秒,而普通查找演算法的耗時卻為4.737秒。

四、折半查找的時間複雜度與查找時間

在平均時間複雜度為O(logn)的前提下,折半查找演算法的查找時間比較快,因為它每次可以將查找範圍縮小為原來的一半。

而在最壞情況下,折半查找的時間複雜度O(logn)也會失效,比如當查找的關鍵字不在序列中時,折半查找會一直循環到我查找範圍為空,這時它的時間複雜度將達到O(n)。

下面的示常式序中,為了讓折半查找失效,我將查找目標設置為0xFFFFFFF(因為序列中最大的數為0x7FFFFFFF,所以它不可能在序列中):

int binary_search(int arr[], int left, int right, int target)
{
    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(arr[mid] == target)
            return mid;
        if(arr[mid] < target)
            left = mid + 1;
        else
            right = mid - 1;
    }
    return -1;
}

int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int ret;

    ret = binary_search(arr, 0, 9, 0xFFFFFFF);
    printf("%d\n", ret);

    return 0;
}

程序會輸出-1,表示查找目標不在序列中。由於這個查找目標不在序列中,折半查找演算法的每次循環都會掃描整個序列,這時時間複雜度會退化為O(n)。

總結

綜上所述,折半查找演算法是一種時間複雜度為O(logn)的快速查找演算法。在數據規模較大的情況下,折半查找演算法明顯比普通查找演算法快許多。但在最壞情況下,它的時間複雜度會失效,這時需要考慮到其他查找演算法。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/234007.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-11 17:12
下一篇 2024-12-11 17:12

相關推薦

  • 解決docker-compose 容器時間和伺服器時間不同步問題

    docker-compose是一種工具,能夠讓您使用YAML文件來定義和運行多個容器。然而,有時候容器的時間與伺服器時間不同步,導致一些不必要的錯誤和麻煩。以下是解決方法的詳細介紹…

    編程 2025-04-29
  • 想把你和時間藏起來

    如果你覺得時間過得太快,每天都過得太匆忙,那麼你是否曾經想過想把時間藏起來,慢慢享受每一個瞬間?在這篇文章中,我們將會從多個方面,詳細地闡述如何想把你和時間藏起來。 一、一些時間管…

    編程 2025-04-28
  • 計算斐波那契數列的時間複雜度解析

    斐波那契數列是一個數列,其中每個數都是前兩個數的和,第一個數和第二個數都是1。斐波那契數列的前幾項為:1,1,2,3,5,8,13,21,34,…。計算斐波那契數列常用…

    編程 2025-04-28
  • 時間戳秒級可以用int嗎

    時間戳是指從某個固定的時間點開始計算的已經過去的時間。在計算機領域,時間戳通常使用秒級或毫秒級來表示。在實際使用中,我們經常會遇到需要將時間戳轉換為整數類型的情況。那麼,時間戳秒級…

    編程 2025-04-28
  • 如何在ACM競賽中優化開發時間

    ACM競賽旨在提高程序員的演算法能力和解決問題的實力,然而在比賽中優化開發時間同樣至關重要。 一、規劃賽前準備 1、提前熟悉比賽規則和題目類型,了解常見演算法、數據結構和快速編寫代碼的…

    編程 2025-04-28
  • 使用JavaScript日期函數掌握時間

    在本文中,我們將深入探討JavaScript日期函數,並且從多個視角介紹其應用方法和重要性。 一、日期的基本表示與獲取 在JavaScript中,使用Date對象來表示日期和時間,…

    編程 2025-04-28
  • Java Date時間大小比較

    本文將從多個角度詳細闡述Java中Date時間大小的比較,包含了時間字元串轉換、日期相減、使用Calendar比較、使用compareTo方法比較等多個方面。相信這篇文章能夠對你解…

    編程 2025-04-27
  • 從時間複雜度角度看循環賽日程表

    循環賽日程表是指在一個比賽中,每個參賽者都需要與其他所有參賽者逐一比賽一次,而且每個參賽者可以在同一場比賽中和其他參賽者比賽多次,比如足球、籃球等。循環賽日程表的設計需要考慮時間復…

    編程 2025-04-27
  • 二分查找時間複雜度為什麼是logN – 知乎

    二分查找是一種常用的查找演算法。它通過將目標值與數組的中間元素進行比較,從而將查找範圍縮小一半,直到找到目標值。這種方法的時間複雜度為O(logN)。下面我們將從多個方面探討為什麼二…

    編程 2025-04-27
  • One change 時間:簡化項目開發的最佳實踐

    本文將介紹 One change 時間 (OCT) 的定義和實現方法,並探討它如何簡化項目開發。OCT 是一種項目開發和管理的策略,通過將更改限制在固定的時間間隔(通常為一周)內,…

    編程 2025-04-27

發表回復

登錄後才能評論