【數據結構與算法基礎】算法復雜度

??歡迎光顧我的homepage

前言

? ? ? ? 算法就是定義良好的計算過程,它取一個活一組的值輸入,并產生出一個或一組值作為輸出。簡單來說,算法就是一系列的計算步驟,用來將輸入數據轉化成輸出結果。

一、算法效率

? ? ? ? 如何去衡量一個算法的好壞?

? ? ? ? 算法在編寫成可執行程序后,運行時消耗時間和空間資源。因此,一般從時間和空間兩個維度來衡量,即時間復雜度和空間復雜度。

時間復雜度和空間復雜度

? ? ? ? 時間復雜度主要衡量一個算法的運行快慢,而空間復雜度主要衡量一個算法運行時所需要的額外空間。? ? ? ?

? ? ? ? 在計算機發展的早期,計算機的存儲容量很小。所以對復雜度很是在乎。但是計算機行業的迅速發展,計算機存儲容量已經達到很高的程度,所以我們并不用特別關注算法的空間復雜度

二、時間復雜度

? ? ? ? 時間復雜度是指算法在執行過程中,所需要的時間資源和問題規模之間的關系,主要衡量算法的運行效率,用來估算算法在不同規模下的運行時間

????????時間復雜度用大O的漸進表示法來表示

2.1時間復雜度的計算

? ? ? ? 算法的時間復雜度是一個函數式T(N),它定量描述了該算法的運行時間。

實際上,我們計算時間復雜度時,計算主要涉及到以下幾個方面

基本操作次數: 時間復雜度的計算通常關注算法中執行的基本操作次數,例如賦值操作、比較操作、算術運算等。通常將這些操作的數量與輸入規模相關聯。

循環結構: 算法包含循環結構,需要考慮循環的迭代次數以及每次迭代中的基本操作數量。

遞歸調用: 對于遞歸算法,需要考慮遞歸的深度以及每次遞歸調用的時間復雜度。通常使用遞歸方程(遞歸關系式)來表示遞歸算法的時間復雜度。

分支結構: 如果算法包含分支結構,需要考慮每個分支的執行次數以及分支中的基本操作數量。

輸入規模: 時間復雜度的計算通常與輸入規模有關。輸入規模表示算法操作的數據量或問題的大小,通常用符號n表示。

? ? ? ? 說白了,算法復雜度其實就是計算基本操作的執行次數
看一個案例,來計算時間復雜度

void Func1(int N)
{int count = 0;for (int i = 0; i < N; ++i){for (int j = 0; j < N; ++j){++count;}}for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}
}

這里Func函數基礎語句執行次數 T(N)=N^2+2N+10

大O的漸進表示法表示就成了 O(N^2)

大O的漸進表示法

1 . 時間復雜度的函數式T(N)中,只保留最高階項,去掉那些低階項

2 . 如果最高項存在且不是1,則去掉這個項的常數系數

3 . T(N)中如果沒有N的相關項,只要常數項,用常數1來取代所有加法常數

2.2、時間復雜度計算實例

2.2.1、示例一

void Func1(int N)
{int count = 0;for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}

Func1函數基本操作次數

???????? T(N)= 2N+10

? ? ? ? 大O漸進表示法? Func1的時間復雜度為:O(N)

2.2.2、示例二

void Func2(int N, int M)
{int count = 0;for (int k = 0; k < M; ++k){++count;}for (int k = 0; k < N; ++k){++count;}printf("%d\n", count);
}

Func1函數基本操作次數

????????T(N)= M+N

? ? ? ? 因為這里無法確定M和N的大小,所以有大O漸進表示法 就為:O(M+N)

2.2.3、示例三

void Func3(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}printf("%d\n", count);
}

Func3函數的基本操作次數

? ? ? ? T(N)=100

? ? ? ? 用大O漸進表示法 表示 O(1)

2.2.4、示例四

const char* strchr(const char* str, int character)
{const char* p_begin = s;while (*p_begin != character){if (*p_begin == '\0')return NULL;p_begin++;}return p_begin;
}

這里計算strchr函數的基本操作次數? ? ? ?

? ? ? ? 如果查找的字符在字符串的第一個位置(靠前的位置)則T(N)= 1

? ? ? ? 如果查找的字符在字符串最后 則T(N)=? N

? ? ? ? 如果查找的字符在字符串中間位置 則T(N)= N/2

這樣用大O漸進表示法就要三種情況

情況一: O(1)????????情況二: O(N)????????情況三: O(N)

這里我們就會發現,有些算法的時間復雜度存在多種情況

? ? ? ? 最好情況 : 任意出入規模的最小運行次數(下界)

? ? ? ? 最壞情況 : 任意輸入規模的最大運行次數(上界)

? ? ? ? 平均情況: 任意輸入規模的期望運行次數

大O漸進表示法在實際情況中一般關注的是算法的上界,也就是最壞運行情況。

所以這里strchr函數的時間復雜度為:O(N)

2.2.5、示例五

void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

冒泡排序的時間復雜度

? ? ? ? 如果數組有序為升序,則T(N) = N (最好情況)

? ? ? ? 如果數組有序為降序,則T(N) = (N*(N+1))/2 (最壞情況)

因此BubbleSort的時間復雜度為 O(N^2)

2.2.6、示例六

void func4(int n)
{int cnt = 1;while (cnt < n){cnt *= 2;}
}

Func4函數

? ? ? ? n=2,執行次數為1

? ? ? ? n=4,執行次數為2

? ? ? ? n=16,執行次數為4

? ? ? ? 當執行次數為x時,n=2^x

? ? ? ? 所以執行次數 x=

所以時間復雜度為:

這里也可以寫成log n

????????當N接近無窮大時,底數的大小對結果影響不大。因此,一般情況下不管底數為多少都可以省略不寫,寫成log n

2.2.7、示例七

long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}

這里每一次調用Fac函數的時間復雜度為O(1)

? ? ? ? 而一共有n次遞歸,所以階乘遞歸的時間復雜度為O(N)

三、空間復雜度

? ? ? ? 空間復雜度也是一個數學表達式,是對一個算法在運行過程中因為算法的需要額外臨時開辟的空間

????????空間復雜度表示程序占用了多少bytes的空間,因為常規情況下每個對象大小 差異不會很大,所以空間復雜度計算的是變量的個數

? ? ? ? 空間復雜度也使用大O漸進表示法

? ? ? ? 這里函數運行時所需要的棧空間(存儲參數,局部變量。一些寄存器信息等)在編譯期間已經確定好了,空間復雜度主要通過函數在運行時顯示申請的額外空間來確定

空間復雜度計算

示例一

void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

函數棧幀在編譯期間已經確定好了,只需關注函數在運行時額外申請的空間

BubbleSort額外申請的空間有exchange等有限個局部變量,使用了常數個額外的空間

? ? ? ? 因此時間復雜度為:O(1)

示例二

long long Fac(size_t N)
{if (N == 0)return 1;return Fac(N - 1) * N;
}

Fac遞歸調用了N次,額外開辟了N個函數棧幀,每個棧幀使用了常數個空間

? ? ? ? 因此時間復雜度為:O(N)

感謝各位大佬支持并指出問題,

????????????????如果本篇內容對你有幫助,可以一鍵三連支持以下,感謝支持!!!

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

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

相關文章

[C++]——同步異步日志系統(3)

同步異步日志系統 一、日志系統框架設計1.1模塊劃分1.1.1 日志等級模塊1.1.2 日志消息模塊1.1.3 日志消息格式化模塊1.1.4 日志落地模塊&#xff08;日志落地的方向是工廠模式&#xff09;1.1.5 日志器模塊&#xff08;日志器的生成是建造者模式&#xff09;1.1.6 異步線程模塊…

Android12上實現雙以太網卡共存同時訪問外網

具體實現如下&#xff1a; 修改main 表優先級到9999&#xff0c; 作用&#xff1a;eth0 eth1 訪問 不去teardown 低分數網線 diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 418e…

Ubuntu 22.04 設置swap交換空間

經常爆內存&#xff0c;導致很多應用沒有辦法一直正常運行&#xff0c;可以通過設置swap來緩解一下&#xff0c;雖然和內存的速度無法媲美&#xff0c;但是能一定程度緩解一下問題。 一、查看當前分區 查看當前系統的swap大小 free -m 二、關閉現有的swap分區 將/etc/fstab…

CUDA Kernel調試與優化--背景知識掃盲(LLM生成)

CUDA Kernel調試與優化–背景知識掃盲(LLM生成) 對于使用CUDA進行調試與性能優化&#xff0c;官方提供了豐富的參考資料和工具。以下是一些關鍵資源&#xff0c;可以幫助你更好地調試和優化CUDA代碼&#xff1a; 官方文檔和指南 CUDA Toolkit Documentation URL: CUDA Toolk…

強化學習總結(有具體代碼實現)

文章目錄 第一部分 強化學習基礎第1章 強化學習概述1.1 強化學習概念1.2 強化學習的環境1.3 強化學習的目標1.4 強化學習的數據 第2章 多臂老虎機問題&#xff08;MAB問題&#xff09;2.1 問題描述2.1.1 問題定義2.1.2 形式化描述2.1.3 累積懊悔2.1.4 估計期望獎勵 2.2 解決方法…

CSS 【詳解】CSS 函數(含 calc,min,max,clamp,cubic-bezier,env,steps 等)

函數描述CSS 版本attr()返回選擇元素的屬性值。2calc()允許計算 CSS 的屬性值&#xff0c;比如動態計算長度值。3cubic-bezier()定義了一個貝塞爾曲線(Cubic Bezier)。3hsl()使用色相、飽和度、亮度來定義顏色。3hsla()使用色相、飽和度、亮度、透明度來定義顏色。3linear-grad…

Bert 變種, T5模型

NLP-預訓練模型-2019-NLU&#xff1a;DistilBERT【 BERT模型壓縮】【模型大小減小了40%&#xff08;66M&#xff09;&#xff0c;推斷速度提升了60%&#xff0c;但性能只降低了約3%】_distillbert-CSDN博客 https://zhuanlan.zhihu.com/p/673535548 大語言模型系列-T5_t5模型…

【機器學習】必會數學知識:一文掌握數據科學核心數學知識點(上),值得收藏~

核心數學知識點 1、引言2、數據科學必會數學知識2.1 線性代數2.2 微積分2.3 概率論2.4 數理統計2.5 隨機過程2.6 數據分布2.7 貝葉斯統計2.8 線性回歸2.9 邏輯回歸2.10 矩陣分解2.11 主成分分析&#xff08;PCA&#xff09;2.12 奇異值分解&#xff08;SVD&#xff09; 3、總結…

【Git 入門】初始化配置與新建倉庫

文章目錄 前言配置git新建倉庫倉庫的概念創建倉庫命令總結前言 在現代軟件開發中,版本控制系統已經成為了不可或缺的工具。其中,Git 是最為廣泛使用的版本控制系統之一。Git 不僅可以幫助我們管理和跟蹤代碼的變化,還可以方便地與他人協作。本文將介紹 Git 的基礎知識,包括…

【人工智能大語言模型技術發展研究報告 2024】

文末?有福利&#xff01; 人工智能作為引領新一輪科技產業革命的戰略性技術和新質生產力重要驅動力&#xff0c;正在引發經濟、社會、文化等領域的變革和重塑&#xff0c;2023 年以來&#xff0c;以 ChatGPT、GPT-4 為代表的大模型技術的出臺&#xff0c;因其強大的內容生成及…

提升教師健康,聚焦智慧校園人事系統的職工體檢功能

智慧校園人事管理系統內置的職工體檢管理&#xff0c;是專為教職員工設計的一項健康管理創新實踐&#xff0c;巧妙融合先進信息技術&#xff0c;致力于為教職工提供更加便捷、易懂且持續性的健康檢查與管理支持。該服務從多個維度出發&#xff0c;全面呵護教職工的身心健康。 該…

給你的博客加上評論區

一個網站如果有評論功能&#xff0c;可以更好的和讀者互動。VuePress 也有很多評論插件&#xff0c;這里簡單介紹下&#xff0c;最后介紹本站所使用的 Twikoo。 大部分評論插件都是使用的 Github 或 Gitee 的 issue 功能&#xff0c;也就是用 issue 去存儲評論&#xff1b;而 …

自然語言處理(NLP)與大語言模型(LLM) 主要差異

一、簡述 NLP 和 LLM 技術是大規模分析和生成人類語言的核心。隨著它們的日益普及&#xff0c;區分 LLM 與 NLP 變得越來越重要。 NLP 包含一套用于理解、操縱和生成人類語言的算法。自 20 世紀 50 年代誕生以來&#xff0c;NLP 已發展到分析文本關系的階段。它使用詞性標注、命…

腳本實現保留文本中特定字符之后的字符串

#目的背景 原始txt文本如下圖 目的是為了去除序號&#xff0c;每行只單獨呈現域名 手工刪除漫長又麻煩&#xff0c;使用腳本快捷些 代碼實現邏輯&#xff1a; 1.使用open函數打開文本&#xff0c;之后用變量lines存儲文本的所有行&#xff0c;使用for循環&#xff0c;讓變量te…

暑假學習計劃怎么做 用待辦計劃軟件安排更科學

暑期來臨&#xff0c;無論是學生還是老師&#xff0c;做好暑期計劃都至關重要。記得去年暑假&#xff0c;我給自己定下了閱讀十本書的目標&#xff0c;卻因為缺乏明確的計劃&#xff0c;最后只草草讀完了兩本。而今年&#xff0c;我決定嘗試一種新的方式——使用待辦計劃軟件來…

大學生數學競賽教程(蒲和平)

大學生數學競賽教程(蒲和平) https://pan.baidu.com/s/1ytcIbVcZpof9WM1xa2dDfA 提取碼: kf2r 源文件來自于&#xff1a;大學生數學競賽教程【蒲和平】

谷粒商城實戰筆記-24-分布式組件-SpringCloud Alibaba-Nacos配置中心-命名空間與配置分組

文章目錄 一&#xff0c;命名空間1&#xff0c;簡介1.1&#xff0c;命名空間的主要功能和特點1.2&#xff0c;使用場景1.3&#xff0c;如何指定命名空間 2&#xff0c;命名空間實戰2.1&#xff0c;環境隔離2.2&#xff0c;服務隔離 二&#xff0c;配置集三&#xff0c;配置集ID…

【數據基礎】— 基于Go1.19的站點模板爬蟲的實現

目錄 1. 定義目標站點 2. 使用Go的庫 3. 發送HTTP請求 4. 解析HTML并提取數據 5. 存儲數據 6. 并發處理 示例代碼 基于Go 1.19的站點模板爬蟲實現通常涉及幾個關鍵步驟&#xff1a;定義目標站點、解析HTML頁面、提取所需數據、存儲數據以及可能的并發處理。下面我將詳細…

js原型和類---prototype,__proto__,new,class

原型和原型鏈 在js中&#xff0c;所有的變量都有原型&#xff0c;原型也可以有原型&#xff0c;原型最終都指向Object 什么是原型 在js中&#xff0c;一個變量被創建出來&#xff0c;它就會被綁定一個原型&#xff1b;比如說&#xff0c;任何一個變量都可以使用console.log打…

PostgreSQL 中如何實現數據的增量更新和全量更新的平衡?

文章目錄 一、增量更新與全量更新的概念增量更新全量更新 二、考慮的因素1. 數據量2. 數據更改的頻率和規模3. 數據一致性要求4. 系統性能和資源利用5. 業務邏輯和流程 三、解決方案&#xff08;一&#xff09;混合使用增量更新和全量更新&#xff08;二&#xff09;使用臨時表…