數據結構入門 — 時間復雜度、空間復雜度

前言

數據結構_空間復雜度_時間復雜度講解_常見復雜度對比

本文介紹數據結構中的時間復雜度和空間復雜度
***文章末尾,博主進行了概要總結,可以直接看總結部分***

博主博客鏈接:https://blog.csdn.net/m0_74014525
點點關注,后期持續更新系列文章


文章目錄

  • 前言
  • 一、算法效率
  • 二、時間復雜度
    • 1. 時間復雜度的定義
    • 2. 大O的漸進表示法
    • 3. 時間復雜度計算舉例
  • 三、空間復雜度
    • 1. 空間復雜度的定義
    • 2. 空間復雜度計算舉例
  • 四、常見復雜度對比
    • 1. 常見的時間復雜度及其對應的算法
    • 2. 常見復雜度的對比
  • 總結


一、算法效率

算法效率指的是算法在處理數據時所消耗的時間和空間資源的多少。

算法效率通常由時間復雜度空間復雜度來衡量。

時間復雜度: 表示算法在處理數據時所需要的運算次數與數據規模之間的關系。

空間復雜度: 表示算法在處理數據時所需要的存儲空間與數據規模之間的關系。

算法效率的好壞直接影響到算法的執行速度和資源利用率,是算法設計時需要考慮的重要因素之一。


二、時間復雜度

1. 時間復雜度的定義

時間復雜度的定義:在計算機科學中,算法的時間復雜度是一個函數,它定量描述了該算法的運行時間。

一個算法執行所耗費的時間,從理論上說,是不能算出來的,只有你把你的程序放在機器上跑起來,才能知道。但是我們需要每個算法都上機測試嗎?是可以都上機測試,但是這很麻煩,所以才有了時間復雜度這個分析方式。

一個算法所花費的時間與其中語句的執行次數成正比例,算法中的基本操作的執行次數,為算法的時間復雜度。

即:找到某條基本語句與問題規模N之間的數學表達式,就是算出了該算法的時間復雜度。

舉例說明:

// 請計算一下Func1中++count語句總共執行了多少次?
void Func1(int N)
{int count = 0;for (int i = 0; i < N; ++i){									//外層循環n次for (int j = 0; j < N; ++j){++count;					//內層循環n次//n*n}}for (int k = 0; k < 2 * N; ++k){++count;					//2*N 次}int M = 10;while (M--){++count;					//循環10次}printf("%d\n", count);
}

Func1 執行的基本操作次數 :

F ( N ) = N 2 + 2 ? N + 10 F(N)=N^2+2*N+10 F(N)=N2+2?N+10
N = 10 F(N) = 130
N = 100 F(N) = 10210
N = 1000 F(N) = 1002010
實際中我們計算時間復雜度時,我們其實并不一定要計算精確的執行次數,而只需要大概執行次數,那么這里我們使用大O的漸進表示法。

使用大O的漸進表示法以后,Func1的時間復雜度為:

O ( N 2 ) O(N^2) O(N2)

N = 10 F(N) = 100
N = 100 F(N) = 10000
N = 1000 F(N) = 1000000
通過上面我們會發現大O的漸進表示法去掉了那些對結果影響不大的項,簡潔明了的表示出了執行次數。


2. 大O的漸進表示法

大O表示法是算法時間復雜度的漸進表示法,表示算法的運行時間在最壞情況下的漸進上限。

大O符號(Big O notation):是用于描述函數漸進行為的數學符號。

推導大O階方法:
1、用常數1取代運行時間中的所有加法常數。
2、在修改后的運行次數函數中,只保留最高階項。
3、如果最高階項存在且不是1,則去除與這個項目相乘的常數。得到的結果就是大O階。

有些算法的時間復雜度存在最好、平均和最壞情況:

最壞情況:任意輸入規模的最大運行次數(上界)
平均情況:任意輸入規模的期望運行次數
最好情況:任意輸入規模的最小運行次數(下界)

在實際中一般情況關注的是算法的最壞運行情況
需要注意的是,大O表示法只關注算法的漸進時間復雜度,而不關注算法的具體實現細節和常數項。因此,兩個算法的時間復雜度可能相同,但它們的實際運行時間可能差別很大,這需要具體問題具體分析。


3. 時間復雜度計算舉例

實例1:

// 計算Func2的時間復雜度?
void Func2(int N)
{int count = 0;for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}

實例1解析:
上述算法基本操作執行了2N+10次,通過推導大O階方法知道,時間復雜度為 O(N)


實例2:

// 計算Func3的時間復雜度?
void Func3(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);
}

實例2解析:
上述算法基本操作執行了M+N次,有兩個未知數M和N,時間復雜度為 O(N+M)


實例3:

// 計算Func4的時間復雜度?
void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}printf("%d\n", count);
}

實例3解析:
上述算法基本操作執行了10次,通過推導大O階方法,時間復雜度為 O(1)


實例4:

// 計算strchr的時間復雜度?
const char * strchr ( const char * str, int character );

實例4解析:
上述算法基本操作執行最好1次,最壞N次,時間復雜度一般看最壞,時間復雜度為 O(N)


實例5:

// 計算BubbleSort的時間復雜度?
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;}
}

實例5解析:
上述算法基本操作執行最好N次,最壞執行了(N*(N+1)/2次,通過推導大O階方法+時間復雜度一般看最壞,時間復雜度為 O(N^2)


實例6:

// 計算BinarySearch的時間復雜度?
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;// [begin, end]:begin和end是左閉右閉區間,因此有=號while (begin <= end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid - 1;elsereturn mid;}return -1;
}

實例6解析:
上述算法基本操作執行最好1次,最壞O(logN)次,時間復雜度為 O(logN)
ps:logN在算法分析中表示是底數為2,對數為N。有些地方會寫成lgN。(建議通過折紙查找的方式講解logN是怎么計算出的)


實例7:

// 計算階乘遞歸Fac的時間復雜度?
long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}

實例7解析:
上述算法通過計算分析發現基本操作遞歸了N次,時間復雜度為O(N)。


實例8:

// 計算斐波那契遞歸Fib的時間復雜度?
long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

實例8解析:
實例8通過計算分析發現基本操作遞歸了2^N次,時間復雜度為O(2^N)


三、空間復雜度

1. 空間復雜度的定義

空間復雜度也是一個數學表達式,是對一個算法在運行過程中臨時占用存儲空間大小的量度 。

空間復雜度不是程序占用了多少bytes的空間,因為這個也沒太大意義,所以空間復雜度算的是變量的個數。空間復雜度計算規則基本跟實踐復雜度類似,也使用大O漸進表示法

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


2. 空間復雜度計算舉例

實例1:

// 計算BubbleSort的空間復雜度?
void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end)   		//end{int exchange = 0;           			//exchangefor (size_t i = 1; i < end; ++i)		//i   {if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

實例1解析:
上面算法里用三個變量,為常數個變量
使用了常數個額外空間,所以空間復雜度為 O(1)


實例2:

// 計算Fibonacci的空間復雜度?
// 返回斐波那契數列的前n項
long long* Fibonacci(size_t n)
{if (n == 0)return NULL;long long* fibArray = (long long*)malloc((n + 1) * sizeof(long long));fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n; ++i){fibArray[i] = fibArray[i - 1] + fibArray[i - 2];}return fibArray;
}

實例2解析:
上面算法使用malloc動態內存函數開辟了N個空間
動態開辟了N個空間,空間復雜度為 O(N)


實例3:

// 計算階乘遞歸Fac的空間復雜度?
long long Fac(size_t N)
{if (N == 0)return 1;return Fac(N - 1) * N;
}

實例3解析:
上述算法使用了遞歸
遞歸調用了N次,開辟了N個棧幀,每個棧幀使用了常數個空間。空間復雜度為O(N)


四、常見復雜度對比

1. 常見的時間復雜度及其對應的算法

大O漸進表示法時間復雜度類型算法的執行時間與輸入規模關系對應算法
O(1)常數時間復雜度表示算法的執行時間與輸入規模無關例如:訪問數組元素、哈希表操作等。
O(log n)對數時間復雜度表示算法的執行時間與輸入規模的對數相關例如:二分查找、平衡二叉樹操作等。
O(n)線性時間復雜度表示算法的執行時間與輸入規模成線性關系例如:線性查找、順序遍歷數組等。
O(n log n)線性對數時間復雜度表示算法的執行時間介于線性和對數之間例如:歸并排序、快速排序等。
O(n^2)平方時間復雜度表示算法的執行時間與輸入規模的平方相關例如:冒泡排序、選擇排序等。
O(n^3)立方時間復雜度表示算法的執行時間與輸入規模的立方相關例如:矩陣乘法等。
O(2^n)指數時間復雜度表示算法的執行時間與輸入規模的指數相關例如:求解子集、窮舉等。

2. 常見復雜度的對比

在這里插入圖片描述


總結

時間復雜度和空間復雜度是用來衡量算法性能的兩個重要指標。

時間復雜度表示算法的運行時間隨著數據規模的增長而增長的趨勢,通常用大O表示法來表示。時間復雜度越低,算法的效率越高。時間復雜度和數據規模之間的關系如下:

  • 常數時間:O(1)
  • 對數時間:O(log n)
  • 線性時間:O(n)
  • 線性對數時間:O(n log n)
  • 平方時間:O(n^2)
  • 立方時間:O(n^3)
  • 指數時間:O(2^n)

空間復雜度表示算法所需內存空間增長的趨勢,同樣用大O表示法來表示。空間復雜度越低,算法所需內存空間越少。空間復雜度和數據規模之間的關系如下:

  • 常數空間:O(1)
  • 線性空間:O(n)
  • 平方空間:O(n^2)

在實際應用中,我們要綜合考慮時間復雜度和空間復雜度,找到一個性能和資源占用的平衡點,以實現最優的算法效果。時間復雜度和空間復雜度是用來衡量算法性能的兩個重要指標。


如這篇博客對大家有幫助的話,希望 三連 支持 !!!

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

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

相關文章

哈夫曼樹(赫夫曼樹、最優樹)詳解

目錄 哈夫曼樹&#xff08;赫夫曼樹、最優樹&#xff09;詳解 哈夫曼樹相關的幾個名詞 什么是哈夫曼樹 構建哈夫曼樹的過程 哈弗曼樹中結點結構 構建哈弗曼樹的算法實現 哈夫曼樹&#xff08;赫夫曼樹、最優樹&#xff09;詳解 哈夫曼樹相關的幾個名詞 路徑&#xff1a;…

2023牛客暑期多校訓練營8(A/H/I/J)

目錄 A.Alive Fossils H.Insert 1, Insert 2, Insert 3, ... I.Make It Square J.Permutation and Primes A.Alive Fossils 思路&#xff1a;一開始題意看半天沒看懂&#xff0c;后面發現只需要輸出t組輸入中&#xff0c;都出現過的字符串即可。 代碼&#xff1a; void s…

實驗三 圖像分割與描述

一、實驗目的&#xff1a; &#xff08;1&#xff09;進一步掌握圖像處理工具Matlab&#xff0c;熟悉基于Matlab的圖像處理函數。 &#xff08;2&#xff09;掌握圖像分割方法&#xff0c;熟悉常用圖像描述方法。 二、實驗原理 1.膚色檢測 膚色是人類皮膚重要特征之一&#xff…

7.原 型

7.1原型 【例如】 另外- this指向&#xff1a; 構造函數和原型對象中的this都指向實例化的對象 7.2 constructor屬性 每個原型對象里面都有個constructor屬性( constructor構造函數) 作用&#xff1a;該屬性指向該原型對象的構造函數 使用場景: 如果有多個對象的方法&#…

Springboot 實踐(4)swagger-ui 測試controller

前文項目操作&#xff0c;完成了項目的創建、數據源的配置以及數據庫DAO程序的生成與配置。此文講解利用swagger-ui界面&#xff0c;測試生成的數據庫DAO程序。目前&#xff0c;項目swagger-ui界面如下&#xff1a; 以”用戶管理”為例&#xff0c;簡單講述swagger-ui測試數據庫…

無涯教程-Perl - s函數

描述 這不是功能。這是正則表達式替換運算符。根據PATTERN中指定的正則表達式,將數據替換為REPLACE。與m //一樣,分隔符由s后的第一個字符定義。 語法 以下是此函數的簡單語法- s/PATTERN/REPLACE/返回值 如果失敗,此函數返回0,如果成功,則返回替換次數。 例 以下是顯示…

筆記:移植xenomai到nuc972

xenomai是一個實時操作系統,想要使用它,先要移植I-pipe補丁 補丁在xenomai / ipipe-arm GitLab 我的內核是4.4-248的,合并上去會有幾個小錯誤,隨便改改就好 編譯內核沒有報錯之后,接下來需要修改arch/arm/mach-nuc970/time.c 修改方法參考補丁里面其它設備的定時器驅動,就…

學習Vue:數據綁定的基本概念

在 Vue.js 中&#xff0c;Vue 實例是您構建應用程序的核心。它允許您將數據和界面連接起來&#xff0c;實現動態的數據綁定&#xff0c;使您的應用程序能夠根據數據的變化自動更新界面。讓我們來深入了解 Vue 實例與數據綁定的基本概念。 Vue 實例與數據綁定 什么是 Vue 實例&…

OPC【2】——Relationships

引言 Relationships由一系列Relationship構成。將Abstract Package看做是一個圖數據結構&#xff0c;則Relationships是圖數據中的邊集合。 Package Relationships 對于Package Relationships&#xff0c;其所有引用關系的source對象為Abstract Package&#xff0c;或者看…

【Python機器學習】實驗10 支持向量機

文章目錄 支持向量機實例1 線性可分的支持向量機1.1 數據讀取1.2 準備訓練數據1.3 實例化線性支持向量機1.4 可視化分析 實例2 核支持向量機2.1 讀取數據集2.2 定義高斯核函數2.3 創建非線性的支持向量機2.4 可視化樣本類別 實例3 如何選擇最優的C和gamma3.1 讀取數據3.2 利用數…

Open3D 最小二乘擬合平面(SVD分解法)

目錄 一、算法原理二、代碼實現三、結果展示1、點云2、擬合結果四、優秀博客本文由CSDN點云俠原創,原文鏈接。爬蟲網站自重。 一、算法原理 本文實現矩陣奇異值分解方法的最小二乘擬合平面。原理如下: 對于得到的 n n

歐拉函數(質因子分解)

思路&#xff1a; (1)歐拉函數&#xff1a;輸入n則輸出1~n中與n互質的數的個數。 &#xff08;2&#xff09;計算公式&#xff1a; &#xff08;3&#xff09;證明&#xff1a;&#xff08;容斥原理&#xff09;對于n個數&#xff0c;先分別摘除所有被pi整除的數&#xff0c;…

億信ABI有什么不同,來看最新DEMO演示

為了給用戶營造更好的體驗環境&#xff0c;提供更豐富、更完善的服務&#xff0c;億信華辰旗下核心產品億信ABI DEMO再次上新啦&#xff01;本次億信ABI DEMO環境在原有基礎上煥新升級&#xff0c;帶來了全新的主視覺界面、豐富的行業應用和功能演示DEMO&#xff0c;我們一起來…

季度到季度的組件選擇

組件&#xff1a;<template><div class"quarter"><div class"input-wrap" id"closeId" mouseover"handler" click.stop"btn" :style"{color:colorItem}"><i class"el-icon-date"&…

【Java】BF算法(串模式匹配算法)

?? 什么是BF算法 BF算法&#xff0c;即暴力算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是將目標串S的第一個與模式串T的第一個字符串進行匹配&#xff0c;若相等&#xff0c;則繼續比較S的第二個字符和T的第二個字符&#xff1b;若不相等&#xff0c;則…

【計算機視覺|生成對抗】用深度卷積生成對抗網絡進行無監督表示學習(DCGAN)

本系列博文為深度學習/計算機視覺論文筆記&#xff0c;轉載請注明出處 標題&#xff1a;Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks 鏈接&#xff1a;[1511.06434] Unsupervised Representation Learning with Deep Conv…

騰訊云CVM服務器競價實例是什么?和按量計費有什么區別?

騰訊云服務器CVM計費模式分為包年包月、按量計費和競價實例&#xff0c;什么是競價實例&#xff1f;競價實例和按量付費相類似&#xff0c;優勢是價格更劃算&#xff0c;缺點是云服務器實例有被自動釋放風險&#xff0c;騰訊云服務器網來詳細說下什么是競價實例&#xff1f;以及…

NLP——操作步驟講義與實踐鏈接

數據集與語料 語料是NLP的生命之源&#xff0c;所有NLP問題都是從語料中學到數據分布的規律語料的分類&#xff1a;單語料&#xff0c;平行語料&#xff0c;復雜結構 語料的例子&#xff1a;Penn Treebank, Daily Dialog, WMT-1x翻譯數據集&#xff0c;中文閑聊數據集&#xf…

大數據:Numpy基礎應用詳解

Numpy基礎應用 Numpy 是一個開源的 Python 科學計算庫&#xff0c;用于快速處理任意維度的數組。Numpy 支持常見的數組和矩陣操作&#xff0c;對于同樣的數值計算任務&#xff0c;使用 NumPy 不僅代碼要簡潔的多&#xff0c;而且 NumPy 的性能遠遠優于原生 Python&#xff0c;…

mysql-5.5.62-win32安裝與使用

1.為啥是這個版本而不是當前最新的8.0&#xff1f; 因為我要用32位。目前mysql支持win32的版本最新只到5.7.33。 首先&#xff0c;到官網MySQL :: MySQL Downloads 然后選 選一個自己喜歡的版本就好。我這里是如標題版本。下載32位的zip。然后回來解壓。 完了創建系統環境變…