數據結構第2問:什么是算法?

算法

算法是一組用于解決具體問題的、明確的、有序的步驟或規則,能夠在有限的時間內通過這些步驟得到問題的答案。

算法的5個重要特性:

  1. 有窮性:算法必須在有限的步驟內結束,不能無限循環,保證最終能夠得到結果。
  2. 確定性:算法的每一步操作都有明確的定義,沒有歧義,保證執行結果唯一。
  3. 可行性:算法的每個步驟都必須是可行的,即能夠在有限時間內通過基本操作完成。
  4. 輸入:算法具有零個或多個輸入,輸入是算法運行所需要的數據。
  5. 輸出:算法至少有一個或多個輸出,輸出是算法處理后的結果。

也就是說,一個基本的算法,必須能夠在有限的步驟內將輸入的數據通過具有確定含義的指令轉換為所需要的輸出結果。

以溫度傳感器原始數據的轉化算法為例

  1. 有窮性:算法在有限步驟內完成原始數據的讀取、處理和轉化,確保不會無限循環,最終輸出轉換后的溫度值。
  2. 確定性:相同的傳感器原始數據通過算法處理后,每次都得到相同且明確的溫度值,步驟明確無歧義。
  3. 可行性:算法使用的操作(如數據讀取、數學計算等)都是實際可執行的,能夠在傳感器所在的硬件環境中完成。
  4. 輸入:算法的輸入是傳感器采集到的原始數據(例如電壓值或數字信號),這些數據用于后續轉換計算。
  5. 輸出:算法輸出轉換后的溫度值(如攝氏度或華氏度),供系統顯示或進一步處理使用。

設計一個好的算法還應該考慮什么?

算法的正確性:即能正確的解決問題。可讀性:算法閱讀起來清晰明了,便于理解。健壯性:算法對于非法數據能做出相應的處理,不會輸出奇怪的數據。高效率與低存儲需求:即算法既要執行的快而準,又要不占用過多存儲空間。

還是拿溫度傳感器來講:好的算法要能正常將溫度值轉化出來;寫的代碼要讓人能看懂好理解;當測試環境溫度超出溫度傳感器量程的時候要做相應處理,不能說單純輸出最大值或者最小值;溫度轉換過程花費的時間要少,占用的flash和ram都要少。(既要又要還要)

衡量一個算法的效率

通常衡量算法效率是通過時間復雜度空間復雜度來描述的。但是一個算法的優劣,不能僅僅依靠時間復雜度和空間復雜度來做出評判。在實際應用中,算法首先要能正確解決問題,然后在效率和內存占用這兩者之間進行權衡。

時間復雜度

一個算法中所有語句在該算法中被重復執行的次數被定義為T(n),時間復雜度則是主要分析T(n)的數量級。因此,通常將算法中基本運算的執行次數的數量級作為該算法的時間復雜度。(即取T(n)中隨n增長最快的項,將其系數置為1,作為時間復雜度的度量)。

  1. 最壞時間復雜度(Worst-case Time Complexity):指算法在所有可能的輸入中,運行時間最長的情況所對應的時間復雜度。它保證了算法在任何輸入下的最大耗時。
  2. 平均時間復雜度(Average-case Time Complexity):指算法在所有可能輸入的概率分布下,運行時間的期望值。它反映了算法在一般情況下的性能表現,但計算比最壞情況復雜。
  3. 最好時間復雜度(Best-case Time Complexity):指算法在所有可能輸入中,運行時間最短的情況所對應的時間復雜度。通常用于了解算法在理想條件下的表現,但不能代表算法的普遍效率。

常見的漸近時間復雜度(從小到大排列)為:

  • O(1) :常數時間復雜度,執行時間固定,不隨輸入規模變化。
  • O(log n) :對數時間復雜度,例如二分查找。
  • O(n) :線性時間復雜度,執行時間隨著輸入規模線性增長。
  • O(n log n) :線性對數時間復雜度,常見于高效排序算法如歸并排序、快速排序。
  • O(n2) :平方時間復雜度,常見于簡單的嵌套循環算法,如冒泡排序。
  • O(n3) :立方時間復雜度,常見于三重嵌套循環的算法。
  • O(2^n) :指數時間復雜度,常見于遞歸求解所有子集等問題。
  • O(n!) :階乘時間復雜度,常見于全排列問題。

時間復雜度的計算

單層循環的時間復雜度計算

觀察變量隨次數的變化規律。

確定循環退出條件。

直接求循環的實際循環次數t。

舉個例子
x = 2
while(x < n/2)x = 2 * x; 

假設運行t次程序退出循環,可得x的值隨t的變化如下:

t1234
x481632

可以得到:
x=2t+1當:x=n/2時退出循環聯立求解t的值得到:t=log2n+2找到增長最快的項為log2n,系數為1所以時間復雜度O(n)=log2n x = 2^{t+1}\\ 當: x = n/2 時退出循環\\ 聯立求解t的值得到:t = log_2n+2\\ 找到增長最快的項為log_2n,系數為1 \\ 所以時間復雜度O(n) = log_2n x=2t+1當:x=n/2時退出循環聯立求解t的值得到:t=log2?n+2找到增長最快的項為log2?n,系數為1所以時間復雜度O(n)=log2?n

再舉個例子
void func(int n)
{int i = 0;while(i*i*i <= n)i++;
}

假設運行t次程序退出循環,可得x的值隨t的變化如下:

t1234
i1234

可以得到:
i=t當:i?i?i=n時退出循環聯立求解t的值得到:t=n3找到增長最快的項為n3,系數為1所以時間復雜度O(n)=n3 i = t\\ 當: i * i * i = n 時退出循環\\ 聯立求解t的值得到:t = \sqrt[3]{n}\\ 找到增長最快的項為\sqrt[3]{n},系數為1 \\ 所以時間復雜度O(n) = \sqrt[3]{n} i=t當:i?i?i=n時退出循環聯立求解t的值得到:t=3n?找到增長最快的項為3n?,系數為1所以時間復雜度O(n)=3n?

兩層循環的時間復雜度計算

  1. 首先確定外層循環的實際循環次數t作為內層循環次數求和的項數;

  2. 然后列出每個外層循環下內層的循環次數;

  3. 最后求和。

舉個例子
int m = 0,i,j;
for(i = 1; i <= n; i++)for(j = 1; j <= 2*i; j++)m++;
計算m++語句的執行次數

先把內層看成O(1),那么外層循環次數為n,再看內層循環的 j 隨運行次數變化:

t_n(項數)1234
j2468

即:
得到j與tn的關系為:j=2tn得到總次數為等差數列求和:總次數=(2+2tn)tn/2已知:內循環退出的臨界點為j=2i,所以tn=i,所以總次數=(2+2i)i/2又已知:外循環退出的臨界點為i=n;所以總次數=n(n+1)得到執行次數為:n(n+1) 得到j與t_n的關系為:j = 2t_n \\ 得到總次數為等差數列求和:總次數=(2 + 2t_n)t_n/2 \\ 已知:內循環退出的臨界點為j = 2i,所以t_n=i,所以總次數=(2 + 2i)i/2 \\ 又已知:外循環退出的臨界點為i = n;所以總次數=n(n + 1) \\ 得到執行次數為:n(n+1) 得到jtn?的關系為:j=2tn?得到總次數為等差數列求和:總次數=(2+2tn?)tn?/2已知:內循環退出的臨界點為j=2i,所以tn?=i,所以總次數=(2+2i)i/2又已知:外循環退出的臨界點為i=n;所以總次數=n(n+1)得到執行次數為:n(n+1)

再舉個例子
int sum = 0;
for(int i=1; i<n; i*=2)for(int j=0; j<i; j++)sum++;
求時間復雜度

先把內層看成O(1),那么外層循環次數為 log?n,再看內層循環的 j 隨運行次數變化:

t_n(項數)1234
j1248


得到j與tn的關系為:j=2tn得到總次數為等比數列求和,公比為2,首項為1,項數為tn?1:總次數=2tn?1?1已知:內循環退出的臨界點為j=i,所以2tn=i,即tn=log2i,所以總次數=2log2i?1?1又已知:外循環退出的臨界點為i=n;所以總次數=2log2n?1?1化簡得總次數為:n/2?1;時間復雜度為O(n) 得到j與t_n的關系為:j = 2^{t_n} \\ 得到總次數為等比數列求和,公比為2,首項為1,項數為t_n-1:總次數= 2^{t_n -1} - 1\\ 已知:內循環退出的臨界點為j = i,所以2^{t_n}=i,即t_n = log_2i,所以總次數= 2^{log_2i-1} - 1\\ 又已知:外循環退出的臨界點為i = n;所以總次數=2^{log_2n-1} - 1 \\ 化簡得總次數為:n/2-1;時間復雜度為O(n) 得到jtn?的關系為:j=2tn?得到總次數為等比數列求和,公比為2,首項為1,項數為tn??1:總次數=2tn??1?1已知:內循環退出的臨界點為j=i,所以2tn?=i,tn?=log2?i,所以總次數=2log2?i?1?1又已知:外循環退出的臨界點為i=n;所以總次數=2log2?n?1?1化簡得總次數為:n/2?1;時間復雜度為O(n)

小結

為了計算內層循環次數累加求和的項數,可以先把內層的時間復雜度看作O(1),然后計算這個條件下外層循環總次數,這樣計算出來的外層循環總次數就是內層循環次數累加求和的項數了

再舉個例子
for(i = n-1; i > 1; i--)for(j = 1; j < i; j++)if(A[j] > A[j+1])A[j] 和 A[j+1]對換

這個就相當于求最壞時間復雜度。

首先把內層看作O(1),那么外層循環次數為 (n-2),再看內層循環的 j 隨運行次數變化:

t_n(項數)1234
jn-2n-3n-4n-51

所以可知:總次數是一個等差數列求和,首項為 (n-2) ,尾項為 1,項數為 (n-2)。

得到:
總次數=([(n?2)+1]?(n?2))/2=(n?1)(n?2)/2時間復雜度為:O(n2) 總次數 = ([(n-2) + 1]*(n-2))/2 = (n-1)(n-2)/2 \\ 時間復雜度為: O(n^2) 總次數=([(n?2)+1]?(n?2))/2=(n?1)(n?2)/2時間復雜度為:O(n2)

多層循環的時間復雜度計算

從內到外進行計算,即內層的次數求和,求和項的項數為相對內層而言的外一層循環看作單層循環時的循環次數。從最內層開始計算,一層一層向外求和。

舉例說明
for(i = 1; i <= n; i++) {             // 外層:n次for(j = 1; j <= i; j++) {         // 中層:i次for(k = 1; k <= j; k++) {     // 內層:j次// O(1)}}
}
  • 內層循環復雜度:
    O(j) O(j) O(j)

  • 中層循環總次數:
    ∑j=1ij=i(i+1)2=O(i2)\sum_{j=1}^{i} j = \frac{i(i+1)}{2} = O(i^2) j=1i?j=2i(i+1)?=O(i2)

  • 外層循環總次數:
    ∑i=1nO(i2)=O(∑i=1ni2)=O(n(n+1)(2n+1)6)=O(n3) \sum_{i=1}^{n} O(i^2) = O\left(\sum_{i=1}^{n} i^2 \right) = O\left(\frac{n(n+1)(2n+1)}{6}\right) = O(n^3) i=1n?O(i2)=O(i=1n?i2)=O(6n(n+1)(2n+1)?)=O(n3)

空間復雜度

空間復雜度S(n)定義為該算法所需的存儲空間,它是問題規模n的函數。

算法的原地工作(In-place):是指算法在執行過程中,只使用常數級別的額外空間(通常是 O(1) 的額外空間),即除了輸入數據本身占用的空間外,不需要額外申請大量存儲空間。這樣,算法直接在輸入的數據結構上進行修改和操作,不借助輔助數組或數據結構。

原地算法的優點是節省內存資源,適合對空間要求較高的場景。例如,原地排序算法(如快速排序、堆排序)就是經典的原地工作的例子。

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

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

相關文章

12-大語言模型—Transformer 打地基,下游任務蓋出百樣房,指標來驗收|下游任務白話指南

目錄 1、核心邏輯&#xff1a;Transformer 的 “語言處理閉環” 2、轉導與感知 → 模型咋 “理解語言”&#xff1f; 2.1、 人類 vs 機器的 “語言理解邏輯” 2.2、 自注意力機制&#xff1a;模型 “理解語言” 的數學核心 2.2.1、通俗拆解 2.2.1.1、是什么&#xff1f; …

深入探索爬蟲與自動化腳本:釋放效率的利器

在當今信息爆炸的時代&#xff0c;高效獲取和處理數據已成為核心競爭力。爬蟲與自動化腳本正是解決這一痛點的關鍵技術——它們如同數字世界的勤勞助手&#xff0c;幫我們自動完成繁瑣重復的任務。下面我們來系統了解這兩項技術的核心要點、應用場景和最佳實踐。一、爬蟲與自動…

React函數組件的“生活管家“——useEffect Hook詳解

&#x1f3af; React函數組件的"生活管家"——useEffect Hook詳解 1. &#x1f31f; 開篇&#xff1a;從生活中的"副作用"說起 嘿&#xff0c;各位掘友們&#xff01;今天咱們來聊聊React函數組件里的一個“大管家”——useEffect Hook。你可能會問&#x…

python基礎:request請求Cookie保持登錄狀態、重定向與歷史請求、SSL證書校驗、超時和重試失敗、自動生成request請求代碼和案例實踐

Cookie保持登錄狀態cookie session鑒權機制 cookie是由web服務器保存在用戶瀏覽器&#xff08;客戶端&#xff09;上的小文本文件&#xff0c;他可以包含有關用戶的信息。無論何時用戶訪問到服務器&#xff0c;都會帶上該服務器的cookie信息&#xff0c;一般cookie都是有有效期…

Vulkan入門教程 | 第二部分:創建實例

前言&#xff1a;本教程為筆者依據教程https://docs.vulkan.net.cn/spec/latest/index.html#_about進行Vulkan學習并結合自己的理解整理的筆記&#xff0c;供大家學習和參考。 &#xff08;注意&#xff1a;代碼僅為片段&#xff0c;非完整程序&#xff09; 學習前提&#xff1…

PHP云原生架構:容器化、Kubernetes與Serverless實踐

引言 隨著云計算的普及,PHP應用也在向云原生架構演進。本文將深入探討PHP在云原生環境中的最佳實踐,包括容器化部署、Kubernetes編排、Serverless架構以及云原生監控與日志方案,幫助開發者構建現代化、可擴展的PHP應用。 容器化PHP應用 基礎Dockerfile優化 # 多階段構建…

【華為機試】5. 最長回文子串

文章目錄5. 最長回文子串描述示例 1示例 2示例 3示例 4提示解題思路方法一&#xff1a;中心擴展法&#xff08;推薦&#xff09;方法二&#xff1a;動態規劃方法三&#xff1a;Manacher算法方法四&#xff1a;暴力解法代碼實現復雜度分析測試用例完整題解代碼5. 最長回文子串 …

【圖像處理基石】如何對遙感圖像進行實例分割?

遙感圖像實例分割是指在遙感影像中&#xff0c;不僅要識別出不同類別的目標&#xff08;如建筑物、車輛、道路等&#xff09;&#xff0c;還要區分同一類別中的不同個體&#xff08;如建筑物1、建筑物2&#xff09;&#xff0c;并為每個實例生成精確的像素級掩碼。 一、遙感圖…

電子電氣架構 --- 軟件bug的管理模式

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

【每日一錯】Oracle 19c CDB中如何啟動一個PDB

文章目錄題目擴展學習CDB與PDB的概念CDB&#xff0c;PDB結構優勢總結題目 擴展學習 CDB與PDB的概念 在Oracle 12c及以上版本&#xff0c;Oracle引入了多租戶架構&#xff0c;這種架構讓數據庫的管理和資源使用更加高效。它由兩種主要組成部分組成&#xff1a; CDB&#xff0…

Android studio自帶的Android模擬器都是x86架構的嗎,需要把arm架構的app翻譯成x86指令?

Android studio自帶的Android模擬器都是x86架構的嗎&#xff0c;需要把arm架構的app翻譯成x86指令&#xff1f; deepseek回答&#xff1a; Android Studio 自帶的官方模擬器&#xff08;Android Emulator&#xff09;主要提供基于 x86 架構的系統鏡像。當運行 ARM 架構的應用…

Deep Learning_ Foundations and Concepts-Springer (2024)【拜讀】20章3節

Diffusion Models 擴散模型 我們已經了解到&#xff0c;構建強大的生成模型的一種有效方法是&#xff1a;先引入一個關于潛在變量z的分布p(z)&#xff0c;然后使用深度神經網絡將z變換到數據空間x。由于神經網絡具有通用性&#xff0c;能夠將簡單固定的分布轉化為關于x的高度靈…

Arduino與STM32:初學者該如何選擇?

在電子愛好者和初學者的世界里&#xff0c;Arduino和STM32是兩個經常被提及的名字。它們各自具有獨特的優勢和特點&#xff0c;適合不同類型的項目和需求。對于初學者來說&#xff0c;選擇Arduino還是STM32&#xff0c;往往取決于個人的學習目標、項目需求以及預算。本文將詳細…

創建型設計模式-工廠方法模式和抽象工廠方法模式

1、工廠方法模式 創建型設計模式之一 UML類圖2、抽象工廠模式 也是創建型設計模式之一。雖然抽象工廠方法模式的類繁多&#xff0c;但是&#xff0c;主要分為4類。 AbstractFactory&#xff1a;抽象工廠角色&#xff0c;它聲明了一組用于創建一種產品的方法&#xff0c;每一個方…

Hyperchain安全與隱私機制詳解

一、核心安全機制1. 共識算法安全RBFT共識算法&#xff1a;改進型PBFT&#xff1a;基于PBFT算法優化&#xff0c;增加動態節點管理、失效數據恢復機制&#xff0c;提升系統容錯性與可用性。性能指標&#xff1a;吞吐量穩定達3000-10000 TPS&#xff0c;交易執行時間控制在300ms…

Oracle優化學習十六

反連接反連接&#xff08;Anti Join&#xff09;是一種特殊的連接類型&#xff0c;與內連接和外連接不同&#xff0c;Oracle數據庫里并沒有相關的 關鍵字可以在SQL文本中專門表示反連接&#xff0c;所以這里把它單獨拿出來說明。為了方便說明反連接的含義&#xff0c;我們用“t…

梳理一些 Docker 常用命令

以下是一些 Docker 常用命令&#xff0c;適用于日常開發、調試、部署等場景&#xff0c;分為幾個常用類別&#xff1a;&#x1f4e6; 一、鏡像&#xff08;Image&#xff09;相關命令命令說明docker images查看本地所有鏡像docker pull <image>拉取鏡像&#xff08;如 do…

C#_ArrayList動態數組

目錄 ArrayList的特點 ArrayList 與普通數組的區別 使用示例&#xff1a; 普通數組 動態數組 主要方法和屬性 屬性&#xff1a; Count 獲取動態數組的數據個數 讀取某個位置的數據 // 索引 方法&#xff1a; Add 向集合末尾添加元素 Insert 在指定位置插入元…

Agent領域,近年來的前沿研究方向:多智能體協作、認知啟發架構、倫理安全、邊緣計算集成

Agent領域,近年來的前沿研究方向:多智能體協作、認知啟發架構、倫理安全、邊緣計算集成 在Agent領域,近年來的前沿研究方向主要集中在多智能體協作、認知啟發架構、倫理安全、邊緣計算集成以及生成式AI融合等方面。 一、多智能體協作與多模態任務 多智能體系統在復雜環境…

【安卓筆記】OOM與內存優化

0. 環境&#xff1a; 電腦&#xff1a;Windows10 Android Studio: 2024.3.2 編程語言: Java Gradle version&#xff1a;8.11.1 Compile Sdk Version&#xff1a;35 Java 版本&#xff1a;Java11 1.什么是OOM OOM即 OutOfMemoryError 內存溢出錯誤。常見于一些 資源型對…