C語言【數據結構】:時間復雜度和空間復雜度.詳解

引言

? ? ? ? 詳細介紹什么是時間復雜度和空間復雜度。

前言:為什么要學習時間復雜度和空間復雜度

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

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

一、時間復雜度?

問:時間復雜度是程序運行的時間嗎?? ? ? ? ? ? ? ? ? ? ?

????????這是一個很嚴重的問題。這里先肯定回答:不是

仔細往下看,最后你親自來回答這個問題?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

1.什么是時間復雜度

????????時間復雜度是對一個算法運行時間長短的一種度量它描述的是隨著輸入數據規模?n?的增大,算法執行時間的增長趨勢,而不是具體的運行時間。因為具體運行時間會受到硬件、編程語言、編譯器等多種因素的影響,所以使用時間復雜度可以更客觀地評估算法的效率。

? ??

程序執行的時間? =? 二進制指令運行的時間 * 執行的次數?

????????因為程序在計算機中二進制指令的運行時間是非常快的,可以假定時間是一樣的,所以使用代碼的執行次數來等效程序的執行時間?

2.表示方法(大O表示法)

????????通常使用大 O 符號(Big O notation)來表示時間復雜度。大 O 符號表示的是算法執行時間的上界,即最壞情況下的時間復雜度。看到這里你可能不知道什么是大O表示法,跟隨下面的案例來理解,就明白什么是大O表示法了。

????????推導大O階規則

????????1. 時間復雜度函數式 T(N) 中,只保留最高階項,去掉那些低階項,因為當 N 不斷變?時, 低階項對結果影響越來越?,當 N 無窮大時,就可以忽略不計了。

???????? 2. 如果最高階項存在且不是 1 ,則去除這個項目的常數系數,因為當 N 不斷變大,這個系數對結果影響越來越小,當 N 無窮大時,就可以忽略不計了。

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

3.常見的時間復雜度

1.?O(1):常數時間復雜度

代碼一:

? ? ? ? 推導一下這段代碼的執行次數T與n之間的函數關系


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);
}

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

當N足夠大時,從1 增長到10000000,會發現2 和10 對次數的影響不是很大,所以

? ? ? ? 1. 如果最高階項存在且不是 1 ,則去除這個項目的常數系數,因為當 N 不斷變大,這個系數對結果影響越來越小,當 N 無窮大時,就可以忽略不計了。

? ? ? ? 2.?T(N) 中如果沒有 N 相關的項目,只有常數項,用常數 1 取代所有加法常數。

代碼二:?

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

????????觀察這段代碼,會發現n和程序的執行次數是沒有關系的(T(N)= 100),這時就認為時間復雜度為O(1);

2.?O(n):線性時間復雜度

代碼一:

????????算法的執行時間與輸入數據規模?n?成正比。

#include <stdio.h>// 計算數組元素的和
int sum(int arr[], int n) {int total = 0;for (int i = 0; i < n; i++) {total += arr[i];}return total;
}int main() {int arr[] = {1, 2, 3, 4, 5};int n = sizeof(arr) / sizeof(arr[0]);int result = sum(arr, n);printf("Sum = %d\n", result);return 0;
}

????????在?sum?函數中,需要遍歷數組中的每個元素,因此循環的執行次數與數組的長度?n?成正比,時間復雜度為?O(n)。即因為是要循環n次,所以是O(n)。

代碼二:?

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執行的基本操作次數:

1)若要查找的字符在字符串第?個位置,則: T(N) = 1

2)若要查找的字符在字符串最后的?個位置, 則: T(N) = N

3)若要查找的字符在字符串中間位置,則:N T(N) = 2 因此:strchr的時間復雜度分為: 最好情況: O(1)

最壞情況: O(N)

平均情況: O(N)



通過上面我們會發現,有些算法的時間復雜度存在最好、平均和最壞情況。

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

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

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

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


所以上面這段代碼的時間復雜度是O(N)

3.?O(n^2):平方時間復雜度

????????算法的執行時間與輸入數據規模?n?的平方成正比。

參考代碼:
#include <stdio.h>// 冒泡排序
void bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, n);for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

粗略理解:在?bubbleSort?函數中,使用了兩層嵌套循環,因此時間復雜度為?O(n^2)。

細節分析:

????????1)若數組有序,則: T(N)=N

? ? ? ? 2)若數組有序且為降序,則: T(N)=? 1 + 2 + 3 + .......+ n - 1 = ((n - 1)?* (1 + n - 1) ) / 2? ?即等差數列求和公式:a1 = 1, an = n - 1, 共n - 1項。

? ? ? ? T(N)= (n^2) * 1 / 2 + n / 2;

???????因此:BubbleSort的時間復雜度取最差情況為: O(N ^ 2)

4.?O(log n ):復雜度

參考代碼:
void func5(int n)
{int cnt = 1;while (cnt < n){cnt *= 2;}
}

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

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

當n=16時,執行次數為4

假設執行次數為x,則 2^x?= x? 因此執行次數: x=logn

因此:func5的時間復雜度取最差情況為:O(log?n)?

這里為什么不寫

因為這個在輸入法上不好打出來

注意:在有的地方會把? logn? 寫成lgn,嚴格上來說這個是不對的

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

還有其他的時間復雜度如:n*logn, n!(n的階乘),在以后的學習中肯定會遇到

二、空間復雜度

?1.什么是空間復雜度

定義

????????空間復雜度是對一個算法在運行過程中臨時占用存儲空間大小的一種度量,它描述的是隨著輸入數據規模?n?的增大,算法所需額外存儲空間增長趨勢。

注意:函數棧幀的創建和銷毀是不算入空間復雜度的,即 創建函數 和 銷毀函數 是不算入時間復雜度的。

表示方法

????????同樣使用大 O 符號來表示空間復雜度。

常見的空間復雜度及其示例代碼

1.?O(1):常數空間復雜度

算法在運行過程中所需的額外存儲空間是固定的,不隨輸入數據規模?n?的變化而變化。

#include <stdio.h>// 計算數組元素的和
int sum(int arr[], int n) {int total = 0;for (int i = 0; i < n; i++) {total += arr[i];}return total;
}int main() {int arr[] = {1, 2, 3, 4, 5};int n = sizeof(arr) / sizeof(arr[0]);int result = sum(arr, n);printf("Sum = %d\n", result);return 0;
}

????????在 sum 函數中,只使用了一個額外的變量?total?來存儲數組元素的和,因此空間復雜度為?O(1)。

2.?O(n):線性空間復雜度

算法在運行過程中所需的額外存儲空間與輸入數據規模?n?成正比。

#include <stdio.h>
#include <stdlib.h>// 復制數組
int* copyArray(int arr[], int n) {int *newArr = (int*)malloc(n * sizeof(int));for (int i = 0; i < n; i++) {newArr[i] = arr[i];}return newArr;
}int main() {int arr[] = {1, 2, 3, 4, 5};int n = sizeof(arr) / sizeof(arr[0]);int *newArr = copyArray(arr, n);for (int i = 0; i < n; i++) {printf("%d ", newArr[i]);}printf("\n");free(newArr);return 0;
}

在copyArray 函數中,使用了 malloc 函數動態分配了一個大小為?n?的數組,因此空間復雜度為?O(n)。?

5. 常見復雜度對比

??

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

? ? ? ? 但是,在算法競賽中,往往需要有一種思想:用時間換空間,或者用空間換時間。

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

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

相關文章

QT:文件讀取

問題&#xff1a; 在文件讀取&#xff0c;判斷md5值時&#xff0c;遇到py文件讀取轉String后&#xff0c;再轉byte&#xff0c;md5前后不一致問題。 解決方法&#xff1a; python文件讀取要使用QTextStream&#xff0c;避免\t 、\r、\n的換行符跨平臺問題&#xff08;window…

32單片機——LED

LED原理圖如圖所示&#xff1a; 代碼 DS0和DS1每過500ms一次交替閃爍&#xff0c;實現類似跑馬燈的效果 GPIO輸出配置步驟 &#xff08;1&#xff09;使能對應GPIO時鐘 STM32在使用任何外設之前&#xff0c;我們都要先使能其時鐘&#xff08;下同&#xff09;。本實驗用到…

貪心算法和遺傳算法優劣對比——c#

項目背景&#xff1a;某鋼管廠的鋼筋原材料為 55米&#xff0c;工作需要需切割 40 米&#xff08;1段&#xff09;、11 米&#xff08;15 段&#xff09;等 4 種規格 &#xff0c;現用貪心算法和遺傳算法兩種算法進行計算&#xff1a; 第一局&#xff1a;{ 40, 1 }, { 11, 15…

【Java篇】一法不變,萬象歸一:方法封裝與遞歸的思想之道

文章目錄 Java 方法的使用&#xff1a;從基礎到遞歸的全面解析一、方法的概念及使用1.1 什么是方法 (method)?1.2 方法定義1.3 方法調用的執行過程1.4 實參和形參的關系1.5 沒有返回值的方法 二、方法重載2.1 為什么需要方法重載2.2 方法重載的概念2.2.4 C 和 Java 的比較&…

深入理解 HTML 中的<div>和元素:構建網頁結構與樣式的基石

一、引言 在 HTML 的世界里&#xff0c;<div>和元素雖看似普通&#xff0c;卻扮演著極為關鍵的角色。它們就像網頁搭建過程中的萬能積木&#xff0c;能夠將各種 HTML 元素巧妙地組合起來&#xff0c;無論是構建頁面布局&#xff0c;還是對局部內容進行樣式調整&#xff…

《大語言模型》學習筆記(一)

一、什么是大語言模型 大語言模型是指在海量無標注文本數據上進行預訓練得到的大型預訓練語言模型&#xff0c;例如GPT-3&#xff0c;PaLM和LLaMA。大語言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;是一種基于深度學習的自然語言處理模型&#xff0c;能…

電力行業中分布式能源管理(Distributed Energy Management System, DEMS)的實現

以下是電力行業中分布式能源管理(Distributed Energy Management System, DEMS)的實現方案,涵蓋系統架構、關鍵技術、核心功能及實施路徑,結合典型場景與代碼示例: 一、系統架構設計 采用云-邊-端三層架構,實現分布式能源的高效協同管理: 1. 終端層(感知層) 設備組…

實驗5 邏輯回歸

實驗5 邏輯回歸 【實驗目的】掌握邏輯回歸算法 【實驗內容】處理樣本&#xff0c;使用邏輯回歸算法進行參數估計&#xff0c;并畫出分類邊界 【實驗要求】寫明實驗步驟&#xff0c;必要時補充截圖 1、參照“2.1梯度下降法實現線性邏輯回歸.ipynb”和“2.2 sklearn實現線性邏輯…

思維訓練讓你更高、更強 |【邏輯思維能力】「刷題訓練筆記」假設法模式邏輯訓練題(1-5)

每日一刷 思維訓練讓你更高、更強&#xff01; 題目1 誰在說謊&#xff0c;誰拿走了零錢&#xff1f; 姐姐上街買菜回來后&#xff0c;就隨手把手里的一些零錢放在了抽屜里&#xff0c;可是&#xff0c;等姐姐下午再去拿錢買菜的時候發現抽屜里的零錢沒有了&#xff0c;于是&…

【愚公系列】《高效使用DeepSeek》004-DeepSeek的產品形態和功能詳解

標題詳情作者簡介愚公搬代碼頭銜華為云特約編輯,華為云云享專家,華為開發者專家,華為產品云測專家,CSDN博客專家,CSDN商業化專家,阿里云專家博主,阿里云簽約作者,騰訊云優秀博主,騰訊云內容共創官,掘金優秀博主,亞馬遜技領云博主,51CTO博客專家等。近期榮譽2022年度…

用python代碼將excel中的數據批量寫入Json中的某個字段,生成新的Json文件

需求 需求&#xff1a; 1.將execl文件中的A列賦值給json中的TrackId&#xff0c;B列賦值給json中的OId 要求 execl的每一行&#xff0c;對應json中的每一個OId json 如下&#xff1a; {"List": [{"BatchNumber": "181-{{var}}",// "Bat…

【Python】dash-fastapi前后端搭建

概述 項目中需要快速搭建一個前后端系統&#xff0c;涉及到dash-fastapi架構的時候&#xff0c;對該架構的時候進行總結。本文主要總結的是對該架構的基本使用&#xff0c;后續再對該架構的項目源碼進行總結分析 此處實現一個小的demo&#xff0c;迷你任務管理器&#xff0c;…

IDEA中鏈接使用mysql數據庫

一、連接mysql 1. 打開idea&#xff0c;在右上角側邊欄有數據庫database插件&#xff0c;打開側邊欄點擊加號->數據源&#xff0c;可以看到支持很多數據庫&#xff0c;選擇mysql。 2. 首次使用需要下載驅動程序&#xff0c;不然連接數據庫會報錯。找到mysql&#xff0c;點擊…

程序編譯生成的文件

目錄 .i 文件 .s 文件 .o文件 總結 在 C 編程中&#xff0c;.i、.s和 .o 文件是編譯過程中生成的不同階段的文件&#xff0c;它們代表不同的含義&#xff1a; .i 文件 全稱 &#xff1a;預處理后的文件&#xff08;Intermediate File&#xff09;。 含義&#xff1a;.i文件…

[S32K]SPI

SpiShiftClockidleLevel: CLK空閑時電平(CPOL)&#xff1b; SpiDataShifrEdge:數據移位邊沿(CPHA)&#xff1b; SpiDataWidth: SpiTransferStart: MSB(高位起始)&#xff0c;LSB(低位起始)&#xff1b;&#xff1b; SpiHwUnit: 這是一個具體的硬件&#xff1f; SpiDataShiftE…

系統思考:客戶價值

“真正的市場競爭&#xff0c;不是比誰更能制造產品&#xff0c;而是比誰更能創造價值。” ——杰夫貝索斯 在組織輔導中&#xff0c;我經常問團隊一個問題&#xff1a;“我們的客戶是誰&#xff1f;”大多數人的第一反應是——“支付費用的就是客戶。” 這在過去的市場擴張階…

ArcGIS Pro 車牌分區數據處理與地圖制作全攻略

在大數據時代&#xff0c;地理信息系統&#xff08;GIS&#xff09;技術在各個領域都有著廣泛的應用&#xff0c;而 ArcGIS Pro 作為一款功能強大的 GIS 軟件&#xff0c;為數據處理和地圖制作提供了豐富的工具和便捷的操作流程。 車牌數據作為一種重要的地理空間數據&#xf…

OpenCV圖像加權函數:addWeighted

1 addWeighted函數 在OpenCV 里&#xff0c;addWeighted 函數的作用是對兩個圖像進行加權求和&#xff0c;常用于圖像融合、圖像過渡等場景。函數如下&#xff1a; cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])2 參數解釋 src1&#xff1a;第一個輸入圖…

Tcp網絡通信的基本流程梳理

先來一張經典的流程圖 接下介紹一下大概流程&#xff0c;各個函數的參數大家自己去了解加深一下印象 服務端流程 1.創建套接字&#xff1a;使用 socket 函數創建一個套接字&#xff0c;這個套接字后續會被用于監聽客戶端的連接請求。 需要注意的是&#xff0c;服務端一般有倆…

mysql學習-刪除數據(drop、truncate、delete)

1、概述 drop、truncate、delete都可以刪除mysql中的數據&#xff0c;但它們的作用范圍和操作方式有很大的不同。 2、詳細區別 2.1、drop 特點&#xff1a; 1、速度快 2、會刪除表數據&#xff0c;還會刪除表結構&#xff0c;包括與該表相關的所有數據&#xff0c;索引&…