網(wǎng)頁制作語言seo優(yōu)化包括哪些內(nèi)容
目錄
1 算法的評價(jià)
2 算法復(fù)雜度
2.1 時(shí)間復(fù)雜度(Time Complexity)
2.1.1 如何計(jì)算時(shí)間復(fù)雜度:
2.1.2 常見的時(shí)間復(fù)雜度類別與示例
2.2?空間復(fù)雜度
2.2.1?如何計(jì)算空間復(fù)雜度
2.2.2 常見的空間復(fù)雜度與示例
3 時(shí)間復(fù)雜度和空間復(fù)雜度計(jì)算示例
例子1:計(jì)算數(shù)組中所有元素的和。
例子2:快速排序算法。
例子3:遞歸實(shí)現(xiàn)斐波那契數(shù)列。
例子4:非遞歸實(shí)現(xiàn)的斐波那契數(shù)列。
例子5:二分查找算法。
例子6:冒泡排序算法。
1 算法的評價(jià)
? ? ? ??評價(jià)算法的性能和效果是計(jì)算機(jī)科學(xué)和數(shù)據(jù)科學(xué)中的關(guān)鍵任務(wù)之一。如何評價(jià)算法的優(yōu)劣可以從以下幾方面展開:
????????時(shí)間復(fù)雜度和空間復(fù)雜度是算法性能分析的關(guān)鍵指標(biāo),它們用于衡量算法在處理不同規(guī)模輸入時(shí)的時(shí)間和空間資源消耗。
2 算法復(fù)雜度
2.1 時(shí)間復(fù)雜度(Time Complexity)
????????時(shí)間復(fù)雜度是指在算法執(zhí)行過程中,所需的時(shí)間資源與問題規(guī)模之間的關(guān)系。它主要衡量的是算法的執(zhí)行效率,用于評估算法在不同規(guī)模數(shù)據(jù)下的操作時(shí)間。
????????時(shí)間復(fù)雜度通常使用大O符號表示,表示算法運(yùn)行時(shí)間的增長率。
?????????需要注意的是,時(shí)間復(fù)雜度只考慮算法的主要操作數(shù)量級,忽略了常數(shù)因子和低階項(xiàng)。因此,兩個(gè)時(shí)間復(fù)雜度相同的算法在實(shí)際執(zhí)行中可能有著不同的執(zhí)行效率。
2.1.1 如何計(jì)算時(shí)間復(fù)雜度:
- 分析每個(gè)操作的時(shí)間復(fù)雜度,包括循環(huán)、條件語句和函數(shù)調(diào)用。
- 計(jì)算每個(gè)操作的執(zhí)行次數(shù),通常是輸入規(guī)模的函數(shù)。
- 合并所有操作的復(fù)雜度,通常選擇最大的那個(gè)作為算法的時(shí)間復(fù)雜度。?
時(shí)間復(fù)雜度的計(jì)算涉及以下幾個(gè)方面:
基本操作次數(shù): 時(shí)間復(fù)雜度的計(jì)算通常關(guān)注算法中執(zhí)行的基本操作次數(shù),例如賦值操作、比較操作、算術(shù)運(yùn)算等。通常將這些操作的數(shù)量與輸入規(guī)模相關(guān)聯(lián)。
循環(huán)結(jié)構(gòu): 如果算法包含循環(huán)結(jié)構(gòu)(例如for循環(huán)、while循環(huán)),需要考慮循環(huán)的迭代次數(shù)以及每次迭代中的基本操作數(shù)量。
遞歸調(diào)用: 對于遞歸算法,需要考慮遞歸的深度以及每次遞歸調(diào)用的時(shí)間復(fù)雜度。通常使用遞歸方程(遞歸關(guān)系式)來表示遞歸算法的時(shí)間復(fù)雜度。
分支結(jié)構(gòu): 如果算法包含分支結(jié)構(gòu)(例如if語句),需要考慮每個(gè)分支的執(zhí)行次數(shù)以及分支中的基本操作數(shù)量。
輸入規(guī)模: 時(shí)間復(fù)雜度的計(jì)算通常與輸入規(guī)模有關(guān)。輸入規(guī)模表示算法操作的數(shù)據(jù)量或問題的大小,通常用符號n表示。
2.1.2 常見的時(shí)間復(fù)雜度類別與示例
常數(shù)時(shí)間復(fù)雜度(O(1)):無論問題規(guī)模多大,算法的執(zhí)行時(shí)間都保持不變。例如,直接訪問數(shù)組中的一個(gè)元素。
線性時(shí)間復(fù)雜度(O(n)):隨著問題規(guī)模的增大,算法的執(zhí)行時(shí)間也按線性比例增長。例如,遍歷一個(gè)數(shù)組或鏈表中的所有元素。
對數(shù)時(shí)間復(fù)雜度(O(logn)):算法執(zhí)行時(shí)間隨著問題規(guī)模的增大而增長,但不是線性關(guān)系,而是以對數(shù)速率增長。例如,二分查找算法。
平方時(shí)間復(fù)雜度(O(n^2)):算法的執(zhí)行時(shí)間與問題規(guī)模的平方成正比。例如,雙重循環(huán)嵌套的算法。
指數(shù)時(shí)間復(fù)雜度(O(2^n)):算法的執(zhí)行時(shí)間呈指數(shù)級增長,非常低效。例如,窮舉法解決NP完全問題。????
O(1) - 常數(shù)時(shí)間復(fù)雜度: 算法的執(zhí)行時(shí)間是固定的,與輸入規(guī)模無關(guān)。示例:
def constant_time_algorithm(arr):return arr[0]
O(log n) - 對數(shù)時(shí)間復(fù)雜度: 算法的執(zhí)行時(shí)間隨著輸入規(guī)模的增加以對數(shù)方式增加。示例:
def binary_search(arr, target):low, high = 0, len(arr) - 1while low <= high:mid = (low + high) // 2if arr[mid] == target:return midelif arr[mid] < target:low = mid + 1else:high = mid - 1return -1
O(n) - 線性時(shí)間復(fù)雜度: 算法的執(zhí)行時(shí)間與輸入規(guī)模成正比。示例
def linear_search(arr, target):for i in range(len(arr)):if arr[i] == target:return ireturn -1
O(n^2) - 平方時(shí)間復(fù)雜度: 算法的執(zhí)行時(shí)間與輸入規(guī)模的平方成正比。示例:
def bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]
2.2?空間復(fù)雜度(Space Complexity)
????????空間復(fù)雜度是指算法在執(zhí)行過程中所需的額外內(nèi)存空間,它與問題規(guī)模之間的關(guān)系。空間復(fù)雜度用于評估算法的內(nèi)存占用情況和資源消耗。
????????通常使用大O符號表示空間復(fù)雜度,表示算法所需的額外內(nèi)存空間與問題規(guī)模之間的增長關(guān)系。
2.2.1?如何計(jì)算空間復(fù)雜度
- 分析算法的每個(gè)數(shù)據(jù)結(jié)構(gòu)、變量和遞歸調(diào)用,以確定它們的空間占用。
- 計(jì)算每個(gè)數(shù)據(jù)結(jié)構(gòu)和變量的空間占用,通常是常數(shù)項(xiàng)和與輸入規(guī)模相關(guān)的項(xiàng)的和。
- 合并所有空間占用,通常選擇最大的那個(gè)作為算法的空間復(fù)雜度。
空間復(fù)雜度的計(jì)算包括以下幾個(gè)方面:
固定內(nèi)存消耗: 指算法在運(yùn)行過程中需要固定數(shù)量的內(nèi)存空間,與輸入規(guī)模無關(guān)。常見的固定內(nèi)存消耗包括函數(shù)參數(shù)、常量變量、全局變量等。
額外數(shù)據(jù)結(jié)構(gòu): 如果算法使用了額外的數(shù)據(jù)結(jié)構(gòu)來存儲信息,如數(shù)組、列表、樹、堆棧、隊(duì)列等,需要考慮這些數(shù)據(jù)結(jié)構(gòu)所占用的內(nèi)存空間。通常需要考慮數(shù)據(jù)結(jié)構(gòu)的大小和數(shù)量。
遞歸調(diào)用: 遞歸算法會使用??臻g來存儲每一次遞歸調(diào)用的狀態(tài)。遞歸的深度和每次遞歸調(diào)用的內(nèi)存消耗會影響空間復(fù)雜度。
臨時(shí)變量: 算法中使用的臨時(shí)變量和計(jì)算過程中的中間結(jié)果也會占用內(nèi)存空間。需要考慮這些變量的數(shù)量和大小。
輸入數(shù)據(jù)的存儲: 輸入數(shù)據(jù)的存儲也需要考慮在內(nèi)。如果算法需要將整個(gè)輸入數(shù)據(jù)存儲在內(nèi)存中,則空間復(fù)雜度與輸入數(shù)據(jù)的大小成正比。
2.2.2 常見的空間復(fù)雜度與示例
常數(shù)空間復(fù)雜度(O(1)):算法所需的額外內(nèi)存空間是一個(gè)常量值,不隨問題規(guī)模的增大而改變。例如,只使用固定數(shù)量的變量或常量大小的數(shù)組。
線性空間復(fù)雜度(O(n)):算法所需的額外內(nèi)存空間隨問題規(guī)模的增大而線性增長。例如,需要根據(jù)輸入構(gòu)建一個(gè)同等大小的新數(shù)據(jù)結(jié)構(gòu)。
平方空間復(fù)雜度(O(n^2)):算法所需的額外內(nèi)存空間隨問題規(guī)模的增大而平方級增長。例如,需要構(gòu)建一個(gè)二維數(shù)組來存儲所有可能的組合。
指數(shù)空間復(fù)雜度(O(2^n)):算法所需的額外內(nèi)存空間隨問題規(guī)模的增大而以指數(shù)級增長。例如,需要存儲所有可能的子集或排列。
????????需要注意的是,空間復(fù)雜度只考慮算法本身所需的額外內(nèi)存空間,不包括輸入數(shù)據(jù)所占用的存儲空間。另外,空間復(fù)雜度也可以根據(jù)最壞情況或平均情況來進(jìn)行分析。
O(1) - 常數(shù)空間復(fù)雜度: 算法的內(nèi)存使用與輸入規(guī)模無關(guān),占用固定的內(nèi)存空間。示例:
def constant_space_algorithm(arr):result = 0for num in arr:result += numreturn result
O(n) - 線性空間復(fù)雜度: 算法的內(nèi)存使用與輸入規(guī)模成正比。示例:
def linear_space_algorithm(n):arr = [0] * nreturn arr
O(n^2) - 平方空間復(fù)雜度: 算法的內(nèi)存使用與輸入規(guī)模的平方成正比。示例:
def quadratic_space_algorithm(n):arr = [[0] * n for _ in range(n)]return arr
3 時(shí)間復(fù)雜度和空間復(fù)雜度計(jì)算示例
例子1:計(jì)算數(shù)組中所有元素的和。
def sum_array(arr):sum = 0for num in arr:sum += numreturn sum
時(shí)間復(fù)雜度:O(n),其中n是數(shù)組中的元素?cái)?shù)量。遍歷數(shù)組需要依次訪問每個(gè)元素一次,因此時(shí)間復(fù)雜度與數(shù)組的大小成線性關(guān)系。
空間復(fù)雜度:O(1)。算法只使用了一個(gè)額外的變量存儲累加和,并沒有占用隨問題規(guī)模變化的額外內(nèi)存。
例子2:快速排序算法。
def quicksort(arr, left, right):if left < right:pivot = partition(arr, left, right)quicksort(arr, left, pivot - 1)quicksort(arr, pivot + 1, right)def partition(arr, left, right):pivot = arr[right]i = left - 1for j in range(left, right):if arr[j] <= pivot:i += 1arr[i], arr[j] = arr[j], arr[i]arr[i + 1], arr[right] = arr[right], arr[i + 1]return i + 1
時(shí)間復(fù)雜度:最好情況下為O(nlogn),最壞情況下為O(n^2)。快速排序平均情況下的劃分操作需要O(n)的時(shí)間復(fù)雜度,且需要遞歸n次,因此總體復(fù)雜度為O(nlogn)。但在最壞情況下,劃分不平衡導(dǎo)致某一邊的規(guī)模接近n,此時(shí)的時(shí)間復(fù)雜度變?yōu)镺(n^2)。
空間復(fù)雜度:最好情況下為O(logn),最壞情況下為O(n)。快速排序使用遞歸調(diào)用,每次遞歸調(diào)用都需要保存當(dāng)前函數(shù)的堆棧信息,而在最壞情況下,可能需要遞歸n次,所以空間復(fù)雜度為O(n)。而在最好情況下,遞歸調(diào)用樹的高度為logn,因此空間復(fù)雜度為O(logn)。
例子3:遞歸實(shí)現(xiàn)斐波那契數(shù)列。
def fibonacci(n):if n <= 0:return 0if n == 1:return 1return fibonacci(n - 1) + fibonacci(n - 2)
時(shí)間復(fù)雜度:指數(shù)級別,為O(2^n)。由于遞歸調(diào)用會重復(fù)計(jì)算相同的斐波那契數(shù),時(shí)間復(fù)雜度呈指數(shù)級增長。
空間復(fù)雜度:最好和最壞情況下均為O(n),取決于遞歸調(diào)用的最大深度n。每次遞歸調(diào)用都需要在堆棧中保存函數(shù)的局部變量和參數(shù),因此空間復(fù)雜度為O(n)。?
該代碼實(shí)現(xiàn)了遞歸方式計(jì)算斐波那契數(shù)列的函數(shù)。
時(shí)間復(fù)雜度:指數(shù)級別,為 O(2^n)。每次遞歸調(diào)用都會產(chǎn)生兩個(gè)新的遞歸調(diào)用,因此遞歸樹的總節(jié)點(diǎn)數(shù)是指數(shù)級別的,遞歸樹的深度是 n。所以,總體的時(shí)間復(fù)雜度是 O(2^n)。
空間復(fù)雜度:指數(shù)級別,為 O(n)。在遞歸調(diào)用過程中,需要使用棧來保存每次遞歸調(diào)用的參數(shù)和局部變量。由于遞歸樹的深度是 n,所以空間復(fù)雜度是 O(n)。
需要注意的是,由于斐波那契數(shù)列的計(jì)算可以通過動態(tài)規(guī)劃或迭代的方式進(jìn)行優(yōu)化,以降低時(shí)間復(fù)雜度和空間復(fù)雜度。遞歸方式計(jì)算斐波那契數(shù)列在面對較大的 n 值時(shí),會導(dǎo)致非常高的時(shí)間和空間消耗。
?例子4:非遞歸實(shí)現(xiàn)的斐波那契數(shù)列。
def fibonacci(n):if n <= 0:return 0a = 0b = 1for _ in range(2, n+1):c = a + ba = bb = creturn b
這段代碼實(shí)現(xiàn)了求解斐波那契數(shù)列的函數(shù)。
該代碼的時(shí)間復(fù)雜度是 O(n),其中 n 是要計(jì)算的斐波那契數(shù)的索引。在 for 循環(huán)中,需要執(zhí)行 n-1 次加法操作。因此,時(shí)間復(fù)雜度是線性級別的。
該代碼的空間復(fù)雜度是 O(1),因?yàn)槌溯斎雲(yún)?shù)外,只使用了常數(shù)空間來存儲變量 a、b 和 c。無論輸入的 n 多大,空間占用都是固定的。
例子5:二分查找算法。
def binary_search(arr, target):low = 0 # 常數(shù)時(shí)間復(fù)雜度high = len(arr) - 1 # 常數(shù)時(shí)間復(fù)雜度while low <= high:mid = (low + high) // 2 # 常數(shù)時(shí)間復(fù)雜度if arr[mid] == target:return midelif arr[mid] < target:low = mid + 1else:high = mid - 1return -1
該算法的時(shí)間復(fù)雜度為O(logn),在二分查找算法中,每次迭代會將問題規(guī)??s小一半,因此時(shí)間復(fù)雜度為對數(shù)級別。具體而言,時(shí)間復(fù)雜度是由二分查找的迭代次數(shù)決定的。
空間復(fù)雜度是 O(1),因?yàn)槌溯斎雲(yún)?shù)外,沒有使用額外的數(shù)據(jù)結(jié)構(gòu)或變量來存儲數(shù)據(jù)。無論輸入規(guī)模如何變化,空間占用都是固定的。
例子6:冒泡排序算法。
def bubble_sort(arr):n = len(arr)for i in range(n): # 線性時(shí)間復(fù)雜度for j in range(0, n-i-1): # 線性時(shí)間復(fù)雜度if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]
時(shí)間復(fù)雜度是 O(n^2),其中 n 是數(shù)組 arr 的長度。冒泡排序算法的時(shí)間復(fù)雜度由兩層嵌套循環(huán)決定。外層循環(huán)執(zhí)行 n 次,內(nèi)層循環(huán)從 0 到 n-i-1 遍歷,其中 i 是外層循環(huán)的迭代次數(shù)。因此,總的比較次數(shù)是 n + (n-1) + (n-2) + ... + 2 + 1,即等差數(shù)列求和公式,可以簡化為 (n^2 - n) / 2,近似為 n^2。因此,該代碼的時(shí)間復(fù)雜度是 O(n^2)。
該代碼的空間復(fù)雜度是 O(1),因?yàn)槌溯斎雲(yún)?shù)外,沒有使用額外的數(shù)據(jù)結(jié)構(gòu)或變量來存儲數(shù)據(jù)。無論輸入規(guī)模如何變化,空間占用都是固定的。
????????計(jì)算時(shí)間復(fù)雜度和空間復(fù)雜度通常需要分析算法的每個(gè)操作以及它們的頻率和內(nèi)存占用。最終,選擇合適的數(shù)據(jù)結(jié)構(gòu)和算法以及考慮性能優(yōu)化策略都有助于確保算法在不同規(guī)模的問題上都能高效運(yùn)行。