【海賊王的數據航海:利用數據結構成為數據海洋的霸主】時間復雜度 | 空間復雜度

目錄

1 -> 算法效率

1.1 -> 如何衡量一個算法的好壞?

1.2 -> 算法的復雜度

2 -> 時間復雜度

2.1 -> 時間復雜度的概念

2.2 -> 大O的漸進表示法

2.3 -> 常見時間復雜度計算

3 -> 空間復雜度

4 -> 常見復雜度對比


1 -> 算法效率

1.1 -> 如何衡量一個算法的好壞?

對于以下斐波那契數列:

#define _CRT_SECURE_NO_WARNINGS#include <iostream>
using namespace std;long long fib(int N)
{if (N < 3)return 1;return fib(N - 1) + fib(N - 2);
}int main()
{return 0;
}

用遞歸實現斐波那契數列,看上去代碼十分簡潔,但簡潔一定就是好算法嗎?如何衡量一個算法的好壞?

1.2 -> 算法的復雜度

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

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

2 -> 時間復雜度

2.1 -> 時間復雜度的概念

定義:在計算機科學中,算法的時間復雜度是一個函數,它定量描述了該算法的運行時間。一個算法執行所耗費的時間,從理論上來講,是不能算出來的,只有把程序放在機器上跑起來才能知道。但是我們需要每個算法都上機測試嗎?固然可以都上機測試,但是這很麻煩,所以才有了時間復雜度這個分析方法。一個算法所花費的時間與其中語句的執行次數成正比例,算法中的基本操作的執行次數,為算法的時間復雜度。

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

#define _CRT_SECURE_NO_WARNINGS#include <iostream>
using namespace std;// 請計算一下Func1中++count語句總共執行了多少次?
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;cout << count << endl;
}int main()
{return 0;
}

Func1執行的基本操作數:

F(N) = N^{2} + 2N + 10

-> N = 10 F(N) = 130
-> N = 100 F(N) = 10210
-> N = 1000 F(N) = 1002010

實際我們在計算時間復雜度時,并不一定要計算精確的執行次數,只需要大概執行次數,所以我們使用大O的漸進表示法。

2.2 -> 大O的漸進表示法

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

推導大O階方法:

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

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

O(N^{2})

-> N = 10 F(N) = 100

-> N = 100 F(N) = 10000
-> N = 1000 F(N) = 1000000

通過上面我們會發現大O的漸進表示法去掉了那些對結果影響不大的項,簡潔明了的表示出了執行次數。?

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

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

例如:在一個長度為N的數組中搜索一個數據x

  • 最好情況:1次找到
  • 平均情況:N / 2次找到
  • 最壞情況:N次找到

在實際中一般情況關注的是算法的最壞運行情況,所以數組中的搜索數據時間復雜度為:

O(N)

2.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;cout << count << endl;
}

實例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;cout << count << endl;
}

實例3:

// 計算Func4的時間復雜度?
void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++k)++count;cout << count << endl;
}

實例4:

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

實例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;}
}

實例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;
}

實例7:

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

實例8:

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

答案及分析:

1. 實例1基本操作執行了2N+10次,通過推導大O階方法知道,時間復雜度為 O(N)
2. 實例2基本操作執行了M+N次,有兩個未知數M和N,時間復雜度為 O(N+M)
3. 實例3基本操作執行了10次,通過推導大O階方法,時間復雜度為 O(1)
4. 實例4基本操作執行最好1次,最壞N次,時間復雜度一般看最壞,時間復雜度為 O(N)
5. 實例5基本操作執行最好N次,最壞執行了(N*(N+1)/2次,通過推導大O階方法+時間復雜度一般看最壞,時間復雜度為 O(N^2)
6. 實例6基本操作執行最好1次,最壞O(logN)次,時間復雜度為 O(logN) ps:logN在算法分析中表示是底數為2,對數為N。有些地方會寫成lgN。
7. 實例7通過計算分析發現基本操作遞歸了N次,時間復雜度為O(N)。
8. 實例8通過計算分析發現基本操作遞歸了2^N次,時間復雜度為O(2^N)。

3 -> 空間復雜度

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

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

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

實例1:

// 計算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;}
}

實例2:

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

實例3:

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

答案及分析:

1. 實例1使用了常數個額外空間,所以空間復雜度為 O(1)
2. 實例2動態開辟了N個空間,空間復雜度為 O(N)
3. 實例3遞歸調用了N次,開辟了N個棧幀,每個棧幀使用了常數個空間。空間復雜度為O(N)

4 -> 常見復雜度對比

一般算法的常見復雜度:

5201314O(1)常數階
3n + 4O(n)線性階
3n ^ 2 + 4n + 5O(n ^ 2)平方階
3log(2)n + 4O(logn)對數階
2n +?3nlog(2)n + 4O(nlogn)nlogn階
n ^ 3 + n ^ 2 + 3n + 4O(n ^ 3)立方階
2 ^ nO(2 ^ n)指數階


感謝大佬們支持!!!

互三啦!!!

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

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

相關文章

nginx前綴匹配

nginx location ^~ /task/ { # 這樣&#xff0c;當您訪問 http://hostname:port/task/test 時&#xff0c;# 請求會被轉發到 proxy_pass /test&#xff0c;注意 /task/ 前綴在轉發時被去掉了。proxy_pass http://192.168.86.199:8805/; proxy_set_header Host $host; proxy…

SQL注入漏洞解析

什么是SQL注入 原理&#xff1a; SQL注入即是指web應用程序對用戶輸入數據的合法性沒有判斷或過濾不嚴&#xff0c;攻擊者可以在web應用程序中事先定義好的查詢語句的結尾上添加額外的SQL語句&#xff0c;在管理員不知情的情況下實現非法操作&#xff0c;以此來實現欺騙數據庫服…

Ps下載安裝(專業圖像處理軟件Ps安裝包下載2024【Windows版】)

Adobe全家桶下載方式 將持續更新~ 文章目錄 Adobe全家桶下載方式Ps下載方式【點我獲取下載鏈接】我們的網站一、Ps簡介聲明 Ps下載方式【點我獲取下載鏈接】 迅雷網盤下載&#xff1a;迅雷網盤下載方式百度網盤下載&#xff1a;百度網盤下載方式夸克網盤下載&#xff1a;夸克…

【Vuforia+Unity】AR01實現單張多張圖片識別產生對應數字內容

1.官網注冊 Home | Engine Developer Portal 2.下載插件SDK&#xff0c;導入Unity 3.官網創建數據庫上傳圖片&#xff0c;官網處理成數據 下載好導入Unity&#xff01; 下載好導入Unity&#xff01; 下載好導入Unity&#xff01; 下載好導入Unity&#xff01; 4.在Unity設…

圖——最小生成樹實現(Kruskal算法,prime算法)

目錄 預備知識&#xff1a; 最小生成樹概念&#xff1a; Kruskal算法&#xff1a; 代碼實現如下&#xff1a; 測試&#xff1a; Prime算法 &#xff1a; 代碼實現如下&#xff1a; 測試&#xff1a; 結語&#xff1a; 預備知識&#xff1a; 連通圖&#xff1a;在無向圖…

Sora的第一波受害者出現了。

不知道大家最近除了被Sora刷屏之外&#xff0c;有沒有被這張圖刷屏 我只能說網友太強大了 說實話&#xff0c;我進入舟老師的直播間&#xff0c;每次都是還有3分鐘下播&#xff0c;還有6單就拍完 但是10分鐘后還在激情逼單&#xff0c;6單之后還有6單 也許在營銷學上&#x…

深入理解nginx的動態變量機制【上】

目錄 1. 概述2. 動態變量的分類2.1 按照變量名的確定性來分類2.2 按照變量聲明的來源分類2.3 按照是否可以變更分類2.4 按照是否可以緩存分類2.5 按照變量的索引方式分類 3. 變量的使用3.1 聲明一個變量3.1.1 支撐變量聲明的nginx關鍵結構體3.1.2 在配置文件中聲明3.1.3 在http…

C++筆記:OOP三大特性之多態

前言 本博客中的代碼和解釋都是在VS2019下的x86程序中進行的&#xff0c;涉及的指針都是 4 字節&#xff0c;如果要其他平臺下測試&#xff0c;部分代碼需要改動。比如&#xff1a;如果是x64程序&#xff0c;則需要考慮指針是8bytes問題等等。 文章目錄 前言一、多態的概念二、…

【C++初階】系統實現日期類

目錄 一.運算符重載實現各個接口 1.小于 (d1)<> 2.等于 (d1d2) 3.小于等于&#xff08;d1<d2&#xff09; 4.大于&#xff08;d1>d2&#xff09; 5.大于等于&#xff08;d1>d2&#xff09; 6.不等于&#xff08;d1!d2&#xff09; 7.日期天數 (1) 算…

mac圖片怎么轉換格式jpg?四種高效方法助你輕松搞定JPG格式

mac圖片怎么轉換格式jpg&#xff1f;在數字時代&#xff0c;圖片格式的轉換成為了我們日常操作中的一項基本技能。特別是在使用Mac操作系統的用戶中&#xff0c;如何將圖片轉換為JPG格式成為了一個熱門話題。本文將為你詳細介紹四種簡單實用的方法&#xff0c;幫助你在Mac上輕松…

測試基礎1:偉大航路喲呼(Linux基礎、mysql基礎)

1 測試流程和方法 軟件測試定義&#xff1a; 從方式上看&#xff1a;包含人工測試、自動化測試 從方法上看&#xff1a;運行程序或系統和測定程序或系統的過程 從目的上看&#xff1a;包括找bug和找bug出現的原因 軟件測試的原則&#xff1a;功能性、可靠性、易用性、效率性…

一、網絡基礎知識

1、IP地址和端口號 1.1、IP地址 定義&#xff1a;用于在網絡中唯一標識設備的地址。格式&#xff1a;通常由四個數字組成&#xff0c;以點分十進制表示&#xff0c;例如&#xff1a;192.168.0.1。(IPv4)作用&#xff1a;允許網絡中的設備相互通信&#xff0c;通過IP地址可以定…

Python 數據可視化之密度散點圖 Density Scatter Plot

&#x1f349; CSDN 葉庭云&#xff1a;https://yetingyun.blog.csdn.net/ 密度散點圖&#xff08;Density Scatter Plot&#xff09;&#xff0c;也稱為密度點圖或核密度估計散點圖&#xff0c;是一種數據可視化技術&#xff0c;主要用于展示大量數據點在二維平面上的分布情況…

Swift基礎知識:24.Swift可選鏈

在 Swift 中&#xff0c;可選鏈&#xff08;Optional Chaining&#xff09;是一種用于調用可選類型屬性、方法或下標的安全方式。可選鏈允許我們在調用鏈中的任何一個屬性、方法或下標返回 nil 時&#xff0c;整個調用鏈仍然可以繼續執行&#xff0c;而不會因為其中的任何一個可…

一樣的代碼不同項目跳轉頁面報404的解決辦法

今天收到實施反饋的一個問題&#xff0c;點項目名稱跳轉項目詳情頁面時&#xff0c;有的頁面跳轉顯示正常&#xff0c;有的頁面跳轉報404錯誤。錯誤如下&#xff1a; 發現報錯的項目都有一個共性就是有特殊字符“[ ]” , 解決的辦法就是把帶有特殊字符的字段 用 encodeURI()…

Java SE 入門到精通—4.抽象類與接口【Java】

抽象類 同接口一樣&#xff0c;用來約束子類&#xff0c;限制子類必須擁有某些方法&#xff0c;比普通類多了個抽象方法&#xff0c;用抽象方法該類必為抽象類 概念 沒有具體的對象&#xff0c;具體的方法的一個類 abstract關鍵字聲明為抽象類/方法 一個類中有抽象方法則該…

統計前端傳過來的Req的非空屬性個數的工具類

背景 日常開發中&#xff0c;我們通常會根據前端傳過來的實體類的屬性個數去做邏輯判斷&#xff0c;下面的是判斷屬性個數的工具類。 工具類 public static Integer nonNullFieldCount(Req req) {if (req null) {return 0;}int nonNullFieldCount 0;Field[] fields req.ge…

【Django】Django自定義后臺表單——對一個關聯外鍵對象同時添加多個內容

以官方文檔為例&#xff1a; 一個投票問題包含多個選項&#xff0c;基本的表單設計只能一個選項一個選項添加&#xff0c;效率較低&#xff0c;如何在表單設計中一次性添加多個關聯選項&#xff1f; 示例代碼&#xff1a; from django.contrib import adminfrom .models impo…

Java中的關鍵字有哪些?它們各自的作用是什么?請詳細說明?Java中的訪問修飾符有哪些?它們的訪問權限是怎樣的?

1、Java中的關鍵字有哪些&#xff1f;它們各自的作用是什么&#xff1f;請詳細說明&#xff1f; Java中的關鍵字是預先定義好的&#xff0c;具有特殊含義的標識符&#xff0c;用于表示數據類型、程序結構或控制流程等。以下是Java中的一些常用關鍵字及其作用&#xff1a; abs…

【軟件架構】02-復雜度來源

1、性能 1&#xff09;單機 受限于主機的CPU、網絡、磁盤讀寫速度等影響 在多線程的互斥性、并發中的同步數據狀態等&#xff1b; 擴展&#xff1a;硬件資源、增大線程池 2&#xff09;集群 微服務化拆分&#xff0c;導致調用鏈過長&#xff0c;網絡傳輸的消耗過多。 集…