數據結構:時間復雜度

文章目錄

  • 為什么需要時間復雜度分析?
  • 一、大O表示法:復雜度的語言
    • 1.1 什么是大O?
    • 1.2 常見復雜度速查表
  • 二、實戰分析:解剖C語言代碼
    • 2.1 循環結構的三重境界
      • 單層循環:線性時間
      • 雙重循環:平方時間
      • 動態邊界循環:隱藏的平方
    • 2.2 遞歸的時空折疊
      • 線性遞歸:階乘計算
      • 指數遞歸:斐波那契噩夢
  • 三、高級技巧:復雜度組合計算
    • 3.1 順序結構:取最大值
    • 3.2 嵌套結構:乘積法則
  • 四、常見誤區與破解之道
    • 誤區1:誤判循環邊界
    • 誤區2:低估數學級數
    • 破解工具:關鍵公式
  • 五、復雜度優化實戰
    • 案例:尋找數組中的重復元素
      • 暴力解法(O(n2))
      • 優化方案(O(n))
  • 六、自測練習
  • 結語:復雜度即格局

為什么需要時間復雜度分析?

想象你正在處理一個包含百萬條數據的數組:

  • O(n2) 的算法可能需要幾天才能完成
  • O(n log n) 的算法可能只需幾秒
  • O(n) 的算法眨眼間就能得出結果

時間復雜度就像算法的「體檢報告」,它揭示了代碼執行效率如何隨數據規模增長而變化。本文將用C語言示例,手把手教你掌握這項核心技能!


一、大O表示法:復雜度的語言

1.1 什么是大O?

  • 本質:描述算法執行時間的增長趨勢
  • 特點:忽略常數項和低階項,專注主要矛盾
  • 公式T(n) = O(f(n)) 表示存在常數C,使得當n足夠大時,T(n) ≤ C·f(n)

1.2 常見復雜度速查表

復雜度典型場景可視化增長趨勢
O(1)數組下標訪問水平直線
O(log n)二分查找緩慢爬坡
O(n)遍歷數組線性上升
O(n log n)快速排序優雅曲線
O(n2)冒泡排序陡峭拋物線
O(2?)暴力窮舉垂直火箭

二、實戰分析:解剖C語言代碼

2.1 循環結構的三重境界

單層循環:線性時間

// 示例:計算數組和
int sum = 0;
for (int i = 0; i < n; i++) {  // 執行n次sum += array[i];           // O(1)操作
}
// 總復雜度:O(n)

雙重循環:平方時間

// 示例:打印所有數對
for (int i = 0; i < n; i++) {       // 外層n次for (int j = 0; j < n; j++) {   // 內層n次printf("(%d,%d)", i, j);    // O(1)操作}
}
// 總復雜度:O(n) × O(n) = O(n2)

動態邊界循環:隱藏的平方

for (int i = 0; i < n; i++) {       // 外層n次for (int j = 0; j < i; j++) {   // 內層i次(0到n-1)count++;                    // 總次數 = 0+1+2+...+(n-1) = n(n-1)/2}
}
// 總復雜度:O(n2)

2.2 遞歸的時空折疊

線性遞歸:階乘計算

int factorial(int n) {if (n <= 1) return 1;          // 基準情形return n * factorial(n-1);     // 遞歸調用n次
}
// 調用棧深度:O(n)
// 時間復雜度:O(n)

指數遞歸:斐波那契噩夢

int fib(int n) {if (n <= 1) return n;return fib(n-1) + fib(n-2);    // 每次產生2個分支
}
// 時間復雜度:O(2?) (實際約為O(1.618?))

遞歸樹呈指數級展開


三、高級技巧:復雜度組合計算

3.1 順序結構:取最大值

void process_data(int n) {// 階段1: O(n)for (int i=0; i<n; i++) { /* ... */ }// 階段2: O(n2)for (int i=0; i<n; i++) {for (int j=0; j<n; j++) { /* ... */ }}
}
// 總復雜度 = O(n) + O(n2) = O(n2)

3.2 嵌套結構:乘積法則

void matrix_ops(int n) {for (int i=0; i<n; i++) {          // O(n)for (int j=1; j<n; j*=2) {     // O(log n)printf("%d", i*j);         // O(1)}}
}
// 總復雜度 = O(n) × O(log n) = O(n log n)

四、常見誤區與破解之道

誤區1:誤判循環邊界

int k = 0;
while (k < 100) {     // 固定循環100次process(data[k++]); 
}
// 真實復雜度:O(1) 而非 O(n)

誤區2:低估數學級數

for (int i=1; i<=n; i*=2) {    // 執行次數:log?nfor (int j=0; j<i; j++) {  // 內層總次數:1+2+4+...+2^log?n = 2n-1count++;}
}
// 總復雜度:O(n) 而非 O(n log n)

破解工具:關鍵公式

  • 等差數列和:1+2+3+...+n = n(n+1)/2 → O(n2)
  • 等比數列和:1+2+4+...+2^k = 2^(k+1)-1 → O(2^k)
  • 對數計算:循環變量i每次乘以2 → 循環次數log?n

五、復雜度優化實戰

案例:尋找數組中的重復元素

暴力解法(O(n2))

for (int i=0; i<n; i++) {for (int j=i+1; j<n; j++) {if (arr[i] == arr[j]) return true;}
}

優化方案(O(n))

// 使用哈希表記錄出現次數
int hash_table[MAX_SIZE] = {0};
for (int i=0; i<n; i++) {if (hash_table[arr[i]]++) return true;
}

六、自測練習

  1. 分析以下代碼復雜度
for (int i=0; i<n; i+=5) {for (int j=0; j<1000; j++) {sum += i*j;}
}

答案:O(n)(外層循環n/5次,內層固定1000次 → 忽略常數后為線性)

  1. 遞歸函數復雜度分析
void fun(int n) {if (n <= 0) return;printf("%d", n);fun(n/2);fun(n/2);
}

答案:O(n)(遞歸樹總節點數=1+2+4+…+n → 約2n個節點)


結語:復雜度即格局


不同復雜度的時間增長對比

掌握時間復雜度分析,就像獲得了一副「算法透視眼鏡」:

  • 在面試中快速評估解法優劣
  • 在大數據場景下避免性能災難
  • 培養對代碼的直覺敏感性

下次看到嵌套循環時,試著在心中畫出它的增長曲線。當復雜度從O(n2)優化到O(n log n)時,那種思維的躍遷感,正是編程最迷人的魔法時刻!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/894545.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/894545.shtml
英文地址,請注明出處:http://en.pswp.cn/news/894545.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

S4 HANA明確稅金匯差科目(OBYY)

本文主要介紹在S4 HANA OP中明確稅金匯差科目(OBYY)相關設置。具體請參照如下內容&#xff1a; 1. 明確稅金匯差科目(OBYY) 以上配置點定義了在外幣掛賬時&#xff0c;當憑證抬頭匯率和稅金行項目匯率不一致時&#xff0c;造成的差異金額進入哪個科目。此類情況只發生在FB60/F…

hypermesh中用tcl腳本生成多個線段

hypermesh中原本有利用多個節點生成線段的功能&#xff0c;但實際應用中不太好用&#xff0c;因為hypermesh會自動對線段進行擬合。如果手動生成多個線段&#xff0c;又太繁瑣&#xff0c;這里寫了一段腳本來自動生成&#xff08;#為注釋符號&#xff09;。 set alist {} for …

87.(3)攻防世界 web simple_php

之前做過&#xff0c;回顧 12&#xff0c;攻防世界simple_php-CSDN博客 進入靶場 <?php // 顯示當前 PHP 文件的源代碼&#xff0c;方便調試或查看代碼結構 // __FILE__ 是 PHP 的一個魔術常量&#xff0c;代表當前文件的完整路徑和文件名 show_source(__FILE__);// 包含…

pycharm 中的 Mark Directory As 的作用是什么?

文章目錄 Mark Directory As 的作用PYTHONPATH 是什么PYTHONPATH 作用注意事項 Mark Directory As 的作用 可以查看官網&#xff1a;https://www.jetbrains.com/help/pycharm/project-structure-dialog.html#-9p9rve_3 我們這里以 Mark Directory As Sources 為例進行介紹。 這…

一個類有一個全局變量 m,多線程對它進行增加操作,如何保證線程安全?

一個類有一個全局變量 m&#xff0c;多線程對它進行增加操作&#xff0c;如何保證線程安全&#xff1f; 在多線程環境下對共享變量進行修改時&#xff0c;確保線程安全的關鍵是保證操作的原子性、可見性和有序性。以下是針對全局變量 m 的多線程自增操作的線程安全解決方案&am…

CSS關系選擇器詳解

CSS關系選擇器詳解 學習前提什么是關系選擇器&#xff1f;后代選擇器&#xff08;Descendant Combinator&#xff09;語法示例注意事項 子代選擇器&#xff08;Child Combinator&#xff09;語法示例注意事項 鄰接兄弟選擇器&#xff08;Adjacent Sibling Combinator&#xff0…

【基于SprintBoot+Mybatis+Mysql】電腦商城項目之用戶注冊

&#x1f9f8;安清h&#xff1a;個人主頁 &#x1f3a5;個人專欄&#xff1a;【計算機網絡】【Mybatis篇】 &#x1f6a6;作者簡介&#xff1a;一個有趣愛睡覺的intp&#xff0c;期待和更多人分享自己所學知識的真誠大學生。 目錄 &#x1f3af;項目基本介紹 &#x1f6a6;項…

Microsoft Power BI:融合 AI 的文本分析

Microsoft Power BI 是微軟推出的一款功能強大的商業智能工具&#xff0c;旨在幫助用戶從各種數據源中提取、分析和可視化數據&#xff0c;以支持業務決策和洞察。以下是關于 Power BI 的深度介紹&#xff1a; 1. 核心功能與特點 Power BI 提供了全面的數據分析和可視化功能&…

電控三周速成計劃參考

第1周&#xff1a;基礎搭建與GPIO控制 學習目標&#xff1a;建立開發環境&#xff0c;掌握最基礎的硬件控制能力 每日學習&#xff08;2-3小時&#xff09;&#xff1a; 環境搭建&#xff08;2天&#xff09; 安裝Keil MDK-ARM STM32CubeMX使用CubeMX創建第一個工程&#xf…

[SAP ABAP] 在ABAP Debugger調試器中設置斷點

在命令框輸入/H&#xff0c;點擊回車以后&#xff0c;調試被激活&#xff0c;點擊觸發任意事件進入ABAP Debugger調試器界面 點擊按鈕&#xff0c;可以在Debugger調試器中新增臨時斷點 我們可以從ABAP命令、方法、功能、表單、異常、消息、源代碼等多個維度在Debugger調試器中設…

【NEXT】網絡編程——上傳文件(不限于jpg/png/pdf/txt/doc等),或請求參數值是file類型時,調用在線服務接口

最近在使用華為AI平臺ModelArts訓練自己的圖像識別模型&#xff0c;并部署了在線服務接口。供給客戶端&#xff08;如&#xff1a;鴻蒙APP/元服務&#xff09;調用。 import核心能力&#xff1a; import { http } from kit.NetworkKit; import { fileIo } from kit.CoreFileK…

RssWebAll:抓取任意網頁的內容生成 RSS 訂閱源

RssWebAll&#xff1a;抓取任意網頁的內容生成 RSS 訂閱源 RssWebAll 是一個強大的工具&#xff0c;可以幫助用戶抓取任意網頁的內容&#xff0c;并生成相應的 RSS 訂閱源&#xff0c;讓用戶隨時隨地獲取他們感興趣的內容更新。 功能亮點 簡單易用&#xff1a;所見即所得&…

從一到無窮大 #43:Presto History Based Optimizer,基于PlanNode粒度統計的查詢計劃選擇策略

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。 本作品 (李兆龍 博文, 由 李兆龍 創作)&#xff0c;由 李兆龍 確認&#xff0c;轉載請注明版權。 文章目錄 引言MotivationArchitectureHBO ScenarioExperiments結束語 引言 過年回家這件事在摯…

【C++】繼承(下)

大家好&#xff0c;我是蘇貝&#xff0c;本篇博客帶大家了解C的繼承&#xff08;下&#xff09;&#xff0c;如果你覺得我寫的還不錯的話&#xff0c;可以給我一個贊&#x1f44d;嗎&#xff0c;感謝?? 目錄 5.繼承與友元6.繼承與靜態成員7.復雜的菱形繼承及菱形虛擬繼承8.繼…

項目開發實踐——基于SpringBoot+Vue3實現的在線考試系統(九)(完結篇)

文章目錄 一、成績查詢模塊實現1、學生成績查詢功能實現1.1 頁面設計1.2 前端頁面實現1.3 后端功能實現2、成績分段查詢功能實現2.1 頁面設計2.2 前端頁面實現2.3 后端功能實現二、試卷練習模塊實現三、我的分數模塊實現1、 頁面設計2、 前端頁面實現3、 后端功能實現四、交流區…

【流媒體】搭建流媒體服務器

搭建Windows Nginx服務器 搭建 下載nginx工具包解壓至本地&#xff0c;并在cmd窗口中切換至nginx所在的本地目錄修改 conf/nginx.conf 文件&#xff0c;更改其端口號 server中的 listen的端口號從 80改為 8080&#xff0c;因為80經常被其他服務占用&#xff0c;導致無法打開 …

攜程Java開發面試題及參考答案 (200道-下)

insert 一行數據的時候加的是什么鎖?為什么? 在 MySQL 中,當執行 INSERT 操作插入一行數據時,加鎖的情況會因存儲引擎和具體的事務隔離級別而有所不同。一般來說,在 InnoDB 存儲引擎下,INSERT 操作加的是行級排他鎖(Row Exclusive Lock),以下詳細說明原因。 行級排他…

洛谷P11655「FAOI-R5」Lovely 139

P11655「FAOI-R5」Lovely 139 題目背景 Update&#xff1a;數據有 0 0&#xff0c;答案為 1&#xff0c;請選手特判以正常通過。 Height ≤ 139 \text{Height}\leq139 Height≤139。 題目描述 對于一個 01 \tt 01 01 串 S S S&#xff08;下標從 1 1 1 開始&#xff09;…

【Linux】24.進程信號(1)

文章目錄 1. 信號入門1.1 進程與信號的相關知識1.2 技術應用角度的信號1.3 注意1.4 信號概念1.5 信號處理常見方式概覽 2. 產生信號2.1 通過終端按鍵產生信號2.2 調用系統函數向進程發信號2.3 由軟件條件產生信號2.4 硬件異常產生信號2.5 信號保存 3. 阻塞信號3.1 信號其他相關…

《手札·開源篇》從開源到商業化:中小企業的低成本數字化轉型路徑 ——以Odoo為數據中臺低成本實現售前售中一體化

某機電設備有限公司數字化轉型案例&#xff1a;以Odoo為數據中臺實現售前售中一體化 一、企業背景某機電設備有限公司在機電設備領域歷經多年發展&#xff0c;業務廣泛&#xff0c;涵蓋工業自動化設備、電力設備等產品的銷售與服務。隨著業務版圖不斷拓展&#xff0c;企業面臨…