數據結構前篇 - 深入解析數據結構之復雜度

目錄

  • 一、數據結構前言
    • 1.1 數據結構
    • 1.2 算法
  • 二、算法效率
    • 2.1 復雜度的概念
  • 三、時間復雜度
    • 3.1 大O的漸進表示法
    • 3.2 時間復雜度計算示例
      • 3.2.1 示例1
      • 3.2.2 示例2
      • 3.2.3 示例3
      • 3.2.4 示例4
      • 3.2.5 示例5
      • 3.2.6 示例6
      • 3.2.7 示例7
  • 四、空間復雜度
    • 4.1 空間復雜度計算示例
      • 4.1.1 示例1
      • 4.1.2 示例2
  • 五、常見復雜度對比
  • 六、復雜度算法題
    • 6.1 旋轉數組
  • 總結


一、數據結構前言

1.1 數據結構

數據結構就是計算機存儲、組織數據的方式,是相互之間存在一種或多種特定關系的數據元素的集合。大多數數據結構的用途都有自己的特性。常見的數據結構有:線性表、樹、圖、哈希等

1.2 算法

我個人認為,算法算法,即是一種解決問題的方法,在計算機中算法就是取一個或一組的值為輸入,并產生一個或一組值作為輸出。簡單來說算法就是一系列的計算步驟,用來將輸入數據轉化成輸出結果。


二、算法效率

這里以一道力扣題來體現算法的效率
輪轉數組
在這里插入圖片描述
在這里插入圖片描述
超出時間限制便是算法效率不夠的原因,代碼是正確的,但當給的數組數據很多的時候,就需要機器處理很長時間才能得出結果,這里就牽扯出了一個概念:復雜度

2.1 復雜度的概念

算法在編寫成可執行程序后,運行時需要耗費時間資源和空間(內存)資源。因此衡量一個算法的好壞,一般是從時間和空間兩個維度來衡量的,即時間復雜度和空間復雜度。

時間復雜度主要衡量一個算法的運行快慢,而空間復雜度主要衡量一個算法運行所需要的額外空間。在計算機發展的早期,計算機的存儲容量很小。所以對空間復雜度很是在乎。但是經過計算機行業的迅速發展,計算機的存儲容量已經達到了很高的程度。所以如今已經不需要再關注一個算法的空間復雜度了。

我個人認為這也是現在游戲優化普遍做的比較一般的原因


三、時間復雜度

定義:在計算機科學中,算法的時間復雜度是一個函數式T(N),這個函數式子就類似于數學中的函數f(x)=ax+b,其圖像是一個值的變化趨勢,函數式子T(N)也是如此。它定量描述了該算法的運行時間。時間復雜度是衡量程序的時間效率,那為什么不直接去計算程序的運行時間呢?

  1. 因為程序運行時間和編譯環境和運行機器的配置都有關系,比如同一個算法程序,用一個老編譯器進行編譯和新編譯器編譯,在同樣機器下運行時間不同。
  2. 同一個算法程序,用一個老低配置機器和新高配置機器,運行時間也不同。
  3. 并且時間只能程序寫好后測試,不能寫程序前通過理論思想計算評估。

在這里插入圖片描述
這個T(N)函數式計算了程序的執行次數。算法程序被編譯后生成二進制指令,程序運行,就是cpu執行這些編譯好的指令。我們可以通過程序代碼或者理論思想計算出程序的執行次數的函數式T(N),假設每句指令執行時間基本一樣(實際中有差別,但微乎其微),那么執行次數和運行時間就是等比正相關,這樣也脫離了具體的編譯運行環境。執行次數就可以代表程序時間效率的優劣。比如解決一個問題的算法a程序T(N)=N,算法b程序T(N)=N2,那么算法a的效率一定優于算法b

案例1:

在這里插入圖片描述

通過對N取值分析,對結果影響最大的一項是N2,這是為什么呢?這里的O又是什么?
實際中計算時間復雜度時,計算的也不是程序的精確的執行次數,精確執行次數計算起來還是很麻煩的(不同的一句程序代碼,編譯出的指令條數都是不一樣的),計算出精確的執行次數意義也不大,因為我們計算時間復雜度只是想比較算法程序的增長量級,也就是當N不斷變大時T(N)的差別,上圖可以看出當N不斷變大時,常數和低階項對結果的影響很小,所以只需要計算程序能代表增長量級的大概執行次數,復雜度的表示通常使用大O的漸進表示法

3.1 大O的漸進表示法

大O符號:是用于描述函數漸進行為的數學符號

推導大O階規則

  1. 時間復雜度函數T(N)中,只保留最高階項,去掉那些低階項,因為當N不斷變大時,低階項對結果影響越來越小,當N無窮大時,就可以忽略不計了。
  2. 如果最高階項存在且系數不是1,則去除這個項目的常數系數,因為當N不斷變大,這個系數對結果影響越來越小,當N無窮大時,就可以忽略不計了。
  3. T(N)中如果沒有N相關的項目,只有常數項,用常數1取代所有加法常數

3.2 時間復雜度計算示例

3.2.1 示例1

在這里插入圖片描述

3.2.2 示例2

在這里插入圖片描述
T(N)里的N不代表任何后面的任何變量,這里的N既可以指代M,也可以指代N

3.2.3 示例3

在這里插入圖片描述

3.2.4 示例4

在這里插入圖片描述
這串代碼的意思是在字符串中查找指定的字符,查找到直接返回,沒有查找到繼續查找,遍歷到字符串結尾還沒有找到,返回NULL

這里若要查找e的話,循環一次,是個常數,所以T(N)=1
若要查找r的話,循環N-2次,所以T(N)=N
若要在中間查找一個字符,則循環N/2次,所以T(N)=N/2

總結:
通過上面可以發現,有些算法的時間復雜度存在最好、平均和最壞的情況
最壞情況:任意輸入規模的最大運行次數(上界)
平均情況:任意輸入規模的期望運行次數
最好情況:任意輸入規模的最小運行次數(下界)
大O的漸進表示法在實際中一般情況關注的是算法的上界,也就是最壞運行情況

3.2.5 示例5

在這里插入圖片描述
外層循環從n到1,循環n次,內存循環從1到n/n-1/… 一直到1,內存循環循環多少次不確定。外層循環n次毋庸置疑
所以這里需要分情況討論
因為外層循環固定n次,把這n次內層循環的次數累加起來,就得到了總的循環的次數
這里看每一次,第一次end=n,第一次內層循環進來,i<n,i的變化1到n-1,循環n-1次
第二次end- -,i<n-1,i的變化為1到n-2,循環n-2次
當第n次,也就是當最后一次end為1,內層循環i<1,條件不滿足,循環不執行
end為2時,也就n-1次,內層循環還會循環一次

剩下如圖中所寫。

3.2.6 示例6

在這里插入圖片描述
這里隨著n的變化,循環次數也在發生變化,然而并不是n是多少,就循環次數是多少
這里與前面執行次數求解不同的原因是cnt不是+1而是×2

這里時間復雜度的寫法看似不對,以2為底怎么能不寫呢,實則是當n接近無窮大時,底數的大小對結果影響不大。因此,一般情況下不管底數是多少都可以省略不寫,即可以表示為log n
不同書籍的表示方法不同,但寫法差別不大

3.2.7 示例7

在這里插入圖片描述
調用Fac的次數等于遞歸的次數,這里要把每次遞歸進行函數調用的時間復雜度累加起來
遞歸是從N-1開始的,N-1到0,遞歸了N次

上面就是所有常見時間復雜度的推理了,雖然有些算法的時間復雜度的推理可能很復雜,但以上這些一般在筆試面試的時候已經夠用


四、空間復雜度

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

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

空間復雜度計算規則基本跟時間復雜度類似,也使用大O漸進表示法

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

4.1 空間復雜度計算示例

4.1.1 示例1

在這里插入圖片描述
函數棧幀在編譯期間已經確定好了,只需要關注函數在運行時額外申請的空間。BubbleSort額外申請的空間有exchange等有限個局部變量,使用了常數個額外空間

因此空間復雜度為O(1)

4.1.2 示例2

在這里插入圖片描述
Fac遞歸調用了N次,額外開辟了N個函數棧幀,每個棧幀使用了常數個空間,因此空間復雜度為O(N)

在這里插入圖片描述
當再動態內存開辟了n個大小的空間時,單詞遞歸的空間復雜度也為N了,空間復雜度就為O(N2

在這里插入圖片描述
單獨動態內存開辟n個大小的空間時,空間復雜度也為O(N)


五、常見復雜度對比

在這里插入圖片描述
在這里插入圖片描述
隨著復雜度增大,程序性能是越差的


六、復雜度算法題

6.1 旋轉數組

再看剛剛的題
在這里插入圖片描述
這道題外層循環k次,內層是numsSize-1變化到1,循環numsSize-1次,模糊認為循環numsSize次,所以認為時間復雜度為O(K*numsSize),K和numsSize均為變量
在這里插入圖片描述
題目給出二者關系:二者一樣大,所以可以認為每個變量時間復雜度為n,這里用n替換了所有的變量,有時不知道兩個或多個變量多大,均視為一樣大

所以這道題的時間復雜度為O(n2),空間復雜度為O(1),因為代碼中沒有額外開辟空間。
時間復雜度太高了,超出時間限制

所以改進的思路也就有了,下降時間復雜度就可以,第一次代碼使用了循環嵌套,所以時間復雜度為n2,改進代碼就不用循環嵌套,用兩次循環,時間復雜度就是O(n)

第一次代碼改進就是額外開辟一個和原數組大小一樣的空間
在這里插入圖片描述
直接對比原數組和輪轉后的數組可以將數組最后k個數據挪到最前面,剩下的數據依次放后面。

這里i來定位原數組的下標,i+k定位新數組的下標,依次把1,2,3,4放到新數組之后,原數組i到了下標為4的位置,此時新數組下標i+k=4+3=7,越界了,這里原數組5要往下標為0的位置放,這里就使用圖中的取余,也不會影響前面數據的存放。
在這里插入圖片描述
該優化算法因為額外開辟的新的空間,所以空間復雜度為O(n),時間復雜度也為O(n),是用空間換時間的一種常見改進思路

再說一種更好的改進思路,既減少了時間復雜度,也不會增加空間復雜度
在這里插入圖片描述
只需要設計一個函數,來完成逆置的操作即可,想使用的時候隨時調用,只要將下標的范圍傳過去就可以了,范圍的下標分別稱為left和right
在這里插入圖片描述
在這里插入圖片描述
一般來說正確的思路如圖,然而卻給出了越界的報錯
在這里插入圖片描述
出現越界的用例如圖:數組中只有一個數據-1,但其輪轉了兩次,就是重復輪轉
這里調用函數,numsSize-k-1=1-2-1=-2,此時left=0,right=-2,沒有進入循環,所以第一次調用沒有出現報錯,緊接著第二次調用numsSize-k=-1,numsSize-1=0,進入循環int tmp=nums[left],沒有-1這個下標,所以溢出了。

所以這里要對k進行特殊處理,首先要理解
當向右輪轉 數組元素個數(即 n 次) 時,相當于每個元素都繞了一圈,又回到最初位置 。比如這個列表 [1,2,3,4,5,6,7] ,元素個數 n = 7:

輪轉 1 次后:[7,1,2,3,4,5,6]
輪轉 2 次后:[6,7,1,2,3,4,5]
……
輪轉 7 次后,每個元素都剛好轉了一圈,又回到初始的 [1,2,3,4,5,6,7] ,所以看起來 “數據不變” 。
而比如說這里numsSize=7,k=14,7個元素輪轉14次還是不變的。
就可以加這樣一句代碼:
在這里插入圖片描述
這里沒有開辟新的空間,所以空間復雜度為O(1),只使用了一次循環,所以時間復雜度為O(n)


總結

以上就是數據結構復雜度的全部內容了,有一說一暑假自律還是有些難度的,喜歡的兄弟們不要忘記一鍵三連給予支持~

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

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

相關文章

Master Prompt:AI時代的萬能協作引擎

1. Master Prompt&#xff1a;為什么它正在重塑AI協作范式大模型落地的最大痛點不是技術本身&#xff0c;而是人機協作的斷裂。當企業采購了昂貴的AI系統&#xff0c;卻發現輸出內容反復偏離預期&#xff0c;團隊成員抱怨“AI總聽不懂我要什么”&#xff0c;這種場景每天在無數…

《Kubernetes部署篇:基于Kylin V10+ARM架構CPU使用containerd部署K8S 1.33.3容器板集群(一主多從)》

總結:整理不易,如果對你有幫助,可否點贊關注一下? 更多詳細內容請參考:企業級K8s集群運維實戰 一、架構圖 如下圖所示: 二、環境信息 基于x86_64+aarch64架構使用containerd部署K8S 1.33.3集群資源合集(一主多從) 2、部署規劃 主機名 K8S版本 系統版本 CPU架構 內核版…

一次性接收大量上傳圖片,后端優化方式

文章目錄1. 分塊接收與流式處理2. 異步處理3. 內存映射與臨時文件4. 數據庫優化5. 緩存策略6. 壓縮與格式優化7. 限流與并發控制8. 分布式存儲9. 響應優化10. 監控與錯誤處理11. 數據庫連接池優化1. 分塊接收與流式處理 使用流式處理避免將所有圖片加載到內存中&#xff1a; …

二分查找(基礎)

競賽中心 - 藍橋云課 #include <iostream> #include<bits/stdc.h> using namespace std; #define int long long int N; struct NO {int A,B; }a[10001]; bool ok(int V) {for (int i 0; i < N; i){if (a[i].A / V ! a[i].B){return false;}}return true; } …

流式編程學習思路

流式編程學習思路 作為Java初級工程師,想要掌握流式編程并向高級工程師進階,需要從基礎到進階逐步掌握,結合實戰場景深化理解。以下是為你量身定制的學習清單和思路: 一、基礎階段:吃透 Java Stream 核心API 1. 掌握 Stream 的基本概念 什么是 Stream:理解它與集合(Co…

13-14linux三劍客grep,sed,awk

目錄 三劍客支持擴展正則寫法 grep命令 sed命令 sed指定行查找&#xff1a; sed模糊過濾文件內容 sed之刪除&#xff1a; sed之替換&#xff1a; sed追加插入替換&#xff1a; sed后向引用&#xff1a; awk命令 awk按照行查找 awk模糊過濾文件內容 awk取列 awk指…

損失函數和調度器相關類代碼回顧理解 |nn.CrossEntropyLoss\CosineAnnealingLR

目錄 nn.CrossEntropyLoss CosineAnnealingLR nn.CrossEntropyLoss loss_func nn.CrossEntropyLoss(reduction"sum") 定義nn.CrossEntropyLoss交叉熵損失函數&#xff0c;reduction參數設置為"sum"&#xff0c;表示將所有樣本的損失相加。reduction 參…

中國不同類型竹林分布數據

中國竹林分布的主要特點簡介&#xff1a;總體分布格局&#xff1a;核心區域&#xff1a; 主要分布在長江流域及以南的廣大亞熱帶和熱帶地區。北界&#xff1a; 大致以黃河流域為北界&#xff0c;但天然成片竹林在秦嶺-淮河一線以南才比較普遍。人工引種或特殊小環境下&#xff…

Sqlserver備份恢復指南-完整備份恢復

博主會用簡單清晰的方式&#xff0c;帶你系統學習使用T-SQL命令行的方式 給SQL Server 做備份與恢復。我們按照從零開始、逐步深入的路線來講解&#xff01; 完整備份恢復-差異增量備份恢復-事務日志備份恢復 &#x1f538; SQL Server 備份類型&#xff1a;類型說明完整備份&a…

AI 調酒師上崗!接管酒吧吧臺

7月29日&#xff0c;馬老師的 HHB 音樂酒吧在阿里巴巴西溪園區正式開業&#xff0c;開業這天迎來了一位神秘嘉賓“AI 調酒師”&#xff01; 這位 AI 調酒師不僅能根據你的MBTI、今日情緒、星座運勢、江湖花名等為你特調一杯雞尾酒&#xff0c;還能為這杯酒配上故事和詩文。 點…

【C++進階】一文吃透靜態綁定、動態綁定與多態底層機制(含虛函數、vptr、thunk、RTTI)

【C進階】一文吃透靜態綁定、動態綁定與多態底層機制&#xff08;含虛函數、vptr、thunk、RTTI&#xff09;作者&#xff1a;你的C教練 日期&#xff1a;2025-08-01目錄 靜態綁定 vs 動態綁定非虛函數的三大坑多態的四要素虛析構函數為什么必須寫&#xff1f;探秘 vptr/vftable…

VUE基礎知識2

1.計算屬性&#xff1a;使用計算屬性來描述依賴響應式狀態的復雜邏輯。關鍵字computed:{}//計算屬性&#xff0c;使用的時候和函數方法不一樣&#xff0c;不需要加括號。簡單來說就是模板方法的復雜邏輯放到了計算屬性中去。2.計算屬性緩存VS方法&#xff1a;計算屬性值會基于其…

在PyCharm中將現有Gitee項目重新上傳為全新項目

如果你想將當前本地的Gitee項目重新上傳為一個全新的Gitee項目&#xff08;保留本地代碼但斷開與原倉庫的關聯&#xff09;&#xff0c;可以按照以下步驟操作&#xff1a; 刪除舊的Git遠程倉庫關聯 打開PyCharm&#xff0c;進入你的項目 點擊頂部菜單 Git > Manage Remotes …

設計模式1:創建型模式

設計模式1&#xff1a;創建型模式 設計模式2&#xff1a;結構型模式&#xff08;編寫中&#xff09; 設計模式3&#xff1a;行為型模式&#xff08;編寫中&#xff09; 前言 設計模式是軟件開發中經過驗證的可復用解決方案&#xff0c;它們源自實踐、提煉于經驗&#xff0c;并…

React--》規劃React組件庫編碼規范與標準 — Button篇

目前前端組件化已經成為前端開發的核心思想之一&#xff0c;在這篇文章中將深入探討如何規劃一個規范的Button組件&#xff0c;讓它不僅能高效支持不同的功能需求還能確保跨項目、跨團隊的一致性&#xff0c;拋磚引玉的方式引出后面組件庫的其他組件的開發&#xff01; 目錄 B…

中科米堆CASAIM金屬件自動3d測量外觀尺寸三維檢測解決方案

金屬零部件的外觀尺寸檢測直接關系到產品的裝配精度和使用性能。CASAIM基于激光掃描技術的自動化三維掃描系統&#xff0c;為金屬加工行業提供了高效的自動3D測量解決方案&#xff0c;有效解決了傳統檢測方式效率低、覆蓋面有限等問題。激光掃描技術在金屬件測量中優勢明顯。與…

開源數據同步中間件,支持MySQL、Oracle

DBSyncer&#xff08;英[dbs??k??(r)]&#xff0c;美[dbs??k??(r) 簡稱dbs&#xff09;是一款開源的數據同步中間件&#xff0c;提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步場景。支持上傳插件自定義同步轉換業務&#xff0…

中英混合的語音識別XPhoneBERT 監督的音頻到音素的編碼器結合 f0 特征LID

完整項目包獲取點擊文末名片完成一個 Code-Switching&#xff08;中英混合&#xff09;的語音識別系統&#xff0c;整個流程如下思路進行&#xff1a; 163. (Step 1) 訓練音頻到音素的編碼器&#xff08;Audio → Phoneme Encoder&#xff09; 你已經完成了此部分。核心思路是利…

Param關鍵字的使用

1&#xff1a;當一個方法的某一個參數個數不固定的時候&#xff0c;可以使用Param2:可變的方法參數必須定義為數組類型3&#xff1a;該參數必須放在方法參數的最后&#xff0c;應且只有一個4&#xff1a;參數必須為一維數組5&#xff1a;params不能和ref和out組合使用namespace…

京東云輕量云服務器與騰訊云域名結合配置網站及申請SSL證書流程詳解

京東云輕量云服務器與騰訊云域名結合配置網站及申請SSL證書流程詳解 1. 需求及實現效果 1.1. 需求 先說一下我當前情況&#xff0c;我目前有一個京東云服務器和一個在騰訊云旗下買的域名&#xff08;不要問為啥一個在京東云&#xff0c;一個在騰訊云&#xff0c;那自然是哪個…