日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法图解

發布時間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法图解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

《算法圖解》各章學習

1、算法簡介

二分法

二分查找法,用于有序元素列表,以一半為界分開,確定元素在哪一部分,繼續前述操作。速度最快,包含n個元素時為 $ \log_2 n$

大O表示法

用于表示算法的速度,O()。真正的速度需要乘以時間常數c,一般分析時不考慮。


2、選擇排序

數組

數組在內存中儲存的信息是連在一起的,方便讀取操作。

鏈表

鏈表的信息在內存中是無序的,下一個內存地址由上一個內存中的信息給出,方便插入和刪除操作。

選擇排序

不斷遍歷整個無序列表,將元素有序排列出來,速度為O(n×n)或O(n2)
(大O表示法省略常數)


3、遞歸

遞歸:自己調用自己的函數。
遞歸函數條件:基線條件和遞歸條件,遞歸條件指的是函數調用自己,而基線條件則指的是函數不再調用自己(例如設置調用次數),從而避免形成無限循環。

棧(stack)

調用棧有壓入和彈出兩個操作,都只操作最上面的內存塊,而不是壓入底部的內存。所有函數調用都進入調用棧。
遞歸時函數不斷將同名不同參考值的函數壓入調用棧,使用時彈出。因此調用棧可能很長,這將占用大量的內存。


4、快速排序

D&C算法思想:找出簡單的基線條件,)確定如何縮小問題的規模,使其符合基線條件。
因此處理列表時基線條件很可能是空數組或只包含一個元素的數組。

快速排序

方法:首先在數組中選擇一個元素作為基準值。接下來,找出比基準值小的元素以及比基準值大的元素各自分為兩個子數組。對子數組進行基準值→子數組的遞歸,直到子數組中只剩1個或沒有元素停止(基線條件)。最后左邊的數組 + 基準值 + 右邊的數組合并為排序結果。
算法速度:實現快速排序時,隨機地選擇用作基準值的元素。快速排序的平均運行時間為O(nlog?n)O(n\log n)O(nlogn),也是最佳情況下的時間,最壞情況(取到了數組中最大或最小的基準值)運行時間是O(n2)。


5、散列表

散列函數

數據的存儲位置和它的關鍵字之間建立一個確定的對應關系f,使每個關鍵字和結構中一個唯一的存儲位置相對應,因此散列函數可以直接確定元素的儲存位置。

散列表(hash table)

使用散列函數和數組創建了一種被稱為散列表 (hash table)的數據結構。Python提供的散列表實現為字典 ,使用函數dict()來創建散列表。
用途:除了快速查找數據以外,還可以用于映射關系,緩存數據(例如,在Web服務器上),防止重復等。
沖突:在散列表中,不同的關鍵字值對應到同一個存儲位置的現象。
處理方法:(1)在沖突的位置儲存一個鏈表,極端情況鏈表很長造成散列表的速度很慢。(2)降低填裝因子,使每個關鍵字都有自己的儲存位置,一旦填裝因子超過0.7,就該加長散列表的長度。(3)良好的散列函數讓數組中的值呈均勻分布。
性能:散列表的查找、插入、刪除在理想情況下均為常量時間O(1).在沖突很多的情況下,速度變慢,最差情況性能變化為線性時間O(n)。


6、廣度優先搜索

圖由節點和邊組成。使用圖來創建問題模型,使用廣度優先搜索解決問題。
廣度優先搜索可回答兩類問題,從節點A出發,有前往節點B的路徑嗎;從節點A出發,前往節點B的哪條路徑最短。

隊列

隊列類似于棧,你不能隨機地訪問隊列中的元素。隊列是一種先進先出 (First In First Out,FIFO)的數據結構,而棧是一種后進先出的數據結構。隊列只支持兩種操作:入隊和出隊 。
在Python中,可使用函數deque()來創建一個雙端隊列。

廣度優先搜索算法

(1)建立圖模型,在這里,要將節點映射到其所有鄰居,如graph["you"] = ["alice", "bob", "claire"]以此類推;
(2)創建隊列,將所有一度關系對象加入隊列,取出隊列的第一個元素并檢查,符合要求結束,不符合則將這個節點的一度關系對象加入隊列;
(3)繼續按順序檢查隊列(否則找到的就不是最短路徑),直到隊列為空或找到需要搜索的對象。檢查隊列時同時將檢查過的對象放入數組中,防止二次檢查浪費時間。

def search(name):search_queue = deque()search_queue += graph[name]searched = []------------------------------這個數組用于記錄檢查過的人while search_queue:person = search_queue.popleft()if person not in searched:----------僅當這個人沒檢查過時才檢查if person_is_seller(person):print person + " is a mango seller!"return Trueelse:search_queue += graph[person]searched.append(person)------將這個人標記為檢查過return False

性能:總運行時間O(V+E)O(V + E)O(V+E),其中V為頂點(vertice)數,E為邊數。


7、狄克斯特拉算法

廣度優先的算法來查找兩點之間的最短距離,那時的“最短距離”是指路徑最少。在狄克斯特拉算法中,你給每段都分配了一個數字或權重,因此狄克斯特拉算法找出的是總權重最小的路徑。

狄克斯特拉算法

(1) 找出最便宜的節點,即可在最短時間內前往的節點。
(2) 對于該節點的鄰居,檢查是否有前往它們的更短路徑,如果有,就更新其開銷。
(3) 重復這個過程,直到對圖中的每個節點都這樣做了。
(4) 計算最終路徑。
注意:僅當權重為正時使用狄克斯特拉算法;如果圖中包含負權邊,則使用貝爾曼-福德算法。

def dijkstra(): //狄克斯特拉算法代碼node = find_lowest_cost_node(costs)------在未處理的節點中找出開銷最小的節點while node is not None:------這個while循環在所有節點都被處理過后結束cost = costs[node]neighbors = graph[node]for n in neighbors.keys():------遍歷當前節點的所有鄰居new_cost = cost + neighbors[n]if costs[n] > new_cost:------如果經當前節點前往該鄰居更近,costs[n] = new_cost ←------就更新該鄰居的開銷parents[n] = node ←------同時將該鄰居的父節點設置為當前節點processed.append(node)------將當前節點標記為處理過node = find_lowest_cost_node(costs)------找出接下來要處理的節點,并循環 def find_lowest_cost_node(costs): //找出開銷最低的節點代碼lowest_cost = float("inf")lowest_cost_node = Nonefor node in costs:------遍歷所有的節點cost = costs[node]if cost < lowest_cost and node not in processed:------如果當前節點的開銷更低且未處理過,lowest_cost = cost ←------就將其視為開銷最低的節點lowest_cost_node = nodereturn lowest_cost_node

8、貪婪算法

對于NP完全問題來說,目前沒有算法能夠快速找到問題的最優解,最佳的做法是使用近似算法(貪婪算法)。
NP完全問題特征:元素較少時算法的運行速度非常快,但隨著元素數量的增加,速度會變得非常慢;不能將問題分成小問題,必須考慮各種可能的情況;問題涉及序列、集合、組合且難以解決。
NP完全問題更加科學的定義關于多項式時間,此處不展開。

貪婪算法

**貪婪算法:**在對問題進行求解時,在每一步選擇中都采取最好或者最優(即最有利)的選擇,從而希望能夠導致結果是最好或者最優的算法。貪婪算法所得到的結果往往不是最優的結果(有時候會是最優解),但是都是相對近似(接近)最優解的結果。

  • 貪婪算法并沒有固定的算法解決框架,算法的關鍵是貪婪策略的選擇,根據不同的問題選擇不同的策略。
  • 必須注意的是策略的選擇必須具備無后效性,即某個狀態的選擇不會影響到之前的狀態,只與當前狀態有關,所以對采用的貪婪的策略一定要仔細分析其是否滿足無后效性。

前面介紹的最短路徑問題,廣度優先、狄克斯特拉都屬于貪婪算法,只是在其問題策略的選擇上,剛好可以得到最優解。


9、動態規劃

動態規劃:在約束條件下,將問題劃分為若干子問題并對其求出最優解,同時將子問題的答案存儲起來,以減少重復計算相同子問題的次數,最終求出問題最優解的算法思想。
書中的例子背包問題,把裝4磅的背包分解為裝1、2、3、4磅的包,把每一步的答案儲存起來,最后的答案取決于前一步答案。這種方法降低了算法的時間復雜度

應用動態規劃(三步走)

1、建立狀態轉移方程:建立如斐波那契數列的遞推方程作為狀態轉移方程,如f(n)=f(n?1)+f(n?2)f (n )=f (n-1)+f(n-2)f(n)=f(n?1)+f(n?2)
**2、緩存并復用以往結果:**記錄下f(1)f(1)f(1)f(2)f(2)f(2)f(99)f(99)f(99),則f(100)f(100)f(100)只需復用前面的子結果,進行一次加法運算即可得到結果。
**3、按順序從小往大算:**這里的“小”和“大”對應的是問題的規模,從小到大一步步遞推出最終的結果。
**例子:**斐波那契數列計算
簡單遞歸:時間復雜度$ O(2^{n})$

動態規劃:線性規劃通過緩存與復用機制將計算規模縮小到紅色部分,時間復雜度$ O(n)$


10、K最近鄰算法

特征提取、分類、回歸,分類時主義選擇合適的公式。(模式識別有詳細講解)


11、其他算法

ⅰ.二叉查找樹

對于其中的每個節點,左子節點的值都比它小 ,而右子節點的值都比它大 。
在二叉查找樹中查找節點時(類似有序數組二分查找操作),平均運行時間為$ O(\log n)$ (二分查找操作同樣為這個),但在最糟的情況下所需時間為$ O(n);插入和刪除操作平均運行時間同樣為;插入和刪除操作平均運行時間同樣為 O(\log n)$。
二叉查找樹不能隨機訪問,如果樹處于不平衡狀態(左右的節點數顯著不等)會導致性能不佳。

ⅱ.反向索引

ⅲ.傅里葉變換

處理信號。
例如傅里葉變換能夠準確地指出各個音符對整個歌曲的貢獻,讓你能夠將不重要的音符刪除。這就是MP3格式的工作原理!

ⅳ.并行算法

排序算法的速度大致為$ O(n\log n),使用并行算法快速排序的所需的時間可以減少為,使用并行算法快速排序的所需的時間可以減少為使 O(n)$。由于并行性管理開銷以及負載需要均衡的原因,并行算法提升速度并不是線性的。

Ⅴ.MapReduce

分布式算法MapReduce基于兩個簡單的理念:映射(map)函數和歸并(reduce)函數。

映射函數

接受一個數組,并對其中的每個元素執行同樣的處理。相當于將多個相同任務映射到多個服務器上去處理。

歸并函數

將很多項歸并為一項,例如吧所有服務器運算得到的結果相加。

ⅵ.布隆過濾器和HyperLogLog

概率型數據結構,不能給出準確的答案,但也較為接近,而占用的內存空間比起散列表卻小得多。

ⅶ.SHA算法

安全散列算法(SHA)函數,給定一個字符串,SHA返回其散列值。這種散列算法是單向的。你可根據字符串計算出散列值,但不能更具散列值計算出字符串。用于比較大型文件,檢查密碼等。

ⅷ.局部敏感的散列算法

SHA重要特征局部不敏感,修改其中的一個字符,再計算其散列值,結果將截然不同。
Simhash散列函數是局部敏感的,對字符串做細微的修改,Simhash生成的散
列值也只存在細微的差別,這能夠通過比較散列值來判斷兩個字符串的相似程度。

Ⅸ.Diffie-Hellman密鑰交換

Diffie-Hellman使用兩個密鑰:公鑰和私鑰。發送消息時使用公鑰對其進行加密。加密后的消息只有使用私鑰才能解密。

Ⅹ.線性規劃

總結

以上是生活随笔為你收集整理的算法图解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。