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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法 Big O 备忘录与现实

發(fā)布時間:2024/9/5 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法 Big O 备忘录与现实 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

不論今天的計算機技術(shù)變化,新技術(shù)的出現(xiàn),所有都是來自數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)。我們需要溫故而知新。

?????? 算法、架構(gòu)、策略、機器學(xué)習(xí)之間的關(guān)系。在過往和技術(shù)人員交流時,很多人對算法和架構(gòu)之間的關(guān)系感到不可理解,算法是軟的,架構(gòu)是硬的,難道算法和架構(gòu)還有什么關(guān)系不成?其實不然,算法和架構(gòu)的關(guān)系非常緊密。在互聯(lián)網(wǎng)時代,我們需要用算法處理的數(shù)據(jù)規(guī)模越來越大,要求的處理時間越來越短,單一計算機的處理能力是不可能滿足需求的。而架構(gòu)技術(shù)的發(fā)展,帶來了很多不同特點的分布式計算平臺。算法為了能夠應(yīng)用到這些分布式計算平臺上,往往需要進化,例如:并行計算要求算法可以拆分為可并行計算的幾個獨立單位,但很多算法不具備這種可拆分特性,使得不能簡單通過分布式計算來提高效率。這時候,為了實現(xiàn)分布式化的計算效果,需要將算法進行等效改寫,使得其具有獨立拆分性。另一方面,算法的發(fā)展,也反過來會對計算架構(gòu)提出新的要求。

?????? 對算法和策略的關(guān)系亦是,不過這兩個概念并不像算法和架構(gòu)那樣好解釋。策略是解決具體問題的手段,而算法是解決一類問題的方法。解決一個具體問題,可能需要將問題分解為一個或者多個算法,一起作用來解決,也可能不需要算法。例如,對于個性化新聞,我們可能有一個策略是:重大新聞需要及時展現(xiàn)給用戶;而實現(xiàn)的具體算法可能只包括“重大新聞挖掘算法”等。

????? 機器學(xué)習(xí)是一類算法的統(tǒng)稱,在一定的數(shù)據(jù)集合上,利用機器學(xué)習(xí)的算法,自動得到規(guī)律,來進行預(yù)測,機器學(xué)習(xí)領(lǐng)域常見的問題包括分類問題、回歸問題等。而預(yù)測,尤其是對用戶的偏好進行預(yù)測是推薦領(lǐng)域的核心問題之一,機器學(xué)習(xí)算法在解決此類問題上會發(fā)生很大的作用。

  • 沒有最好的算法,只有合適的算法。推薦算法和產(chǎn)品需求、應(yīng)用場景、數(shù)據(jù)密切相關(guān),不要相信有什么包打天下的算法;
  • 數(shù)據(jù)是基礎(chǔ):數(shù)據(jù)充足而且質(zhì)量高,簡單算法也可以有不錯的效果;反之,則多好的算法也不可能有好的效果;
  • 木桶效應(yīng):算法策略要和用戶需求、功能展現(xiàn)密切配合;(注:木桶原理又稱短板理論,其核心內(nèi)容為“一只木桶盛水的多少,并不取決于桶壁上最高的那塊木塊,而恰恰取決于桶壁上最短的那塊。”)
  • 一般而言,推薦算法都需要考慮是否能處理大數(shù)據(jù),是否能大規(guī)模并行化。

?

正文

一、數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)

數(shù)組

定義

  • 按順序連續(xù)存儲數(shù)據(jù)元素,通常索引從0開始
  • 以集合論中的元組為基礎(chǔ)
  • 數(shù)組是最古老,最常用的數(shù)據(jù)結(jié)構(gòu)

知識要點

  • 索引最優(yōu);不利于查找、插入和刪除(除非在數(shù)組最末進行)
  • 最基礎(chǔ)的是線性數(shù)組或一維數(shù)組
    數(shù)組長度固定,意味著聲明數(shù)組時應(yīng)指明長度
  • 動態(tài)數(shù)組與一維數(shù)組類似,但為額外添加的元素預(yù)留了空間
    如果動態(tài)數(shù)組已滿,則把每一元素復(fù)制到更大的數(shù)組中
  • 類似網(wǎng)格或嵌套數(shù)組,二維數(shù)組有 x 和 y 索引

時間復(fù)雜度

  • O(1)索引:一維數(shù)組:O(1),動態(tài)數(shù)組:O(1)
  • O(n)查找:一維數(shù)組:O(n),動態(tài)數(shù)組:O(n)
  • O(log n)最優(yōu)查找:一維數(shù)組:O(log n),動態(tài)數(shù)組:O(log n)
  • O(n)插入:一維數(shù)組:n/a,動態(tài)數(shù)組:O(n)

鏈表

定義

  • 結(jié)點存儲數(shù)據(jù),并指向下一結(jié)點
    最基礎(chǔ)的結(jié)點包含一個數(shù)據(jù)和一個指針(指向另一結(jié)點)
    • 鏈表靠結(jié)點中指向下一結(jié)點的指針連接成鏈

要點

  • 為優(yōu)化插入和刪除而設(shè)計,但不利于索引和查找
  • 雙向鏈表包含指向前一結(jié)點的指針
  • 循環(huán)鏈表是一種終端結(jié)點指針域指向頭結(jié)點的簡單鏈表
  • 堆棧通常由鏈表實現(xiàn),不過也可以利用數(shù)組實現(xiàn)
    堆棧是“后進先出”(LIFO)的數(shù)據(jù)結(jié)構(gòu)
    • 由鏈表實現(xiàn)時,只有頭結(jié)點處可以進行插入或刪除操作
  • 同樣地,隊列也可以通過鏈表或數(shù)組實現(xiàn)
    隊列是“先進先出”(FIFO)的數(shù)據(jù)結(jié)構(gòu)
    • 由雙向鏈表實現(xiàn)時,只能在頭部刪除,在末端插入

時間復(fù)雜度

  • O(n)索引:鏈表:O(n)
  • O(n)查找:鏈表:O(n)
  • Linked Lists: O(n)最優(yōu)查找:鏈表:O(n)
  • O(1)插入:鏈表:O(1)

哈希表或哈希圖

定義

  • 通過鍵值對進行儲存
  • 哈希函數(shù)接受一個關(guān)鍵字,并返回該關(guān)鍵字唯一對應(yīng)的輸出值
    這一過程稱為散列(hashing),是輸入與輸出一一對應(yīng)的概念
    • 哈希函數(shù)為該數(shù)據(jù)返回在內(nèi)存中唯一的存儲地址

要點

  • 為查找、插入和刪除而設(shè)計
  • 哈希沖突是指哈希函數(shù)對兩個不同的數(shù)據(jù)項產(chǎn)生了相同的輸出值
    所有的哈希函數(shù)都存在這個問題
    • 用一個非常大的哈希表,可以有效緩解這一問題
    • 哈希表對于關(guān)聯(lián)數(shù)組和數(shù)據(jù)庫檢索十分重要

時間復(fù)雜度

  • O(1)索引:哈希表:O(1)
  • O(1)查找:哈希表:O(1)
  • O(1)插入:哈希表:O(1)

二叉樹

定義

  • 一種樹形的數(shù)據(jù)結(jié)構(gòu),每一結(jié)點最多有兩個子樹
    • 子結(jié)點又分為左子結(jié)點和右子結(jié)點

要點

  • 為優(yōu)化查找和排序而設(shè)計
  • 退化樹是一種不平衡的樹,如果完全只有一邊,其本質(zhì)就是一個鏈表
  • 相比于其他數(shù)據(jù)結(jié)構(gòu),二叉樹較為容易實現(xiàn)
  • 可用于實現(xiàn)二叉查找樹
    • 二叉樹利用可比較的鍵值來確定子結(jié)點的方向
    • 左子樹有比雙親結(jié)點更小的鍵值
    • 右子樹有比雙親結(jié)點更大的鍵值
    • 重復(fù)的結(jié)點可省略
    • 由于上述原因,二叉查找樹通常被用作一種數(shù)據(jù)結(jié)構(gòu),而不是二叉樹

時間復(fù)雜度

  • 索引:二叉查找樹:O(log n)
  • 查找:二叉查找樹:O(log n)
  • 插入:二叉查找樹:O(log n)

二、搜索基礎(chǔ)

廣度優(yōu)先搜索

定義

  • 一種在樹(或圖)中進行搜索的算法,從根結(jié)點開始,優(yōu)先按照樹的層次進行搜索
    • 搜索同一層中的各結(jié)點,通常從左往右進行
    • 進行搜索時,同時追蹤當(dāng)前層中結(jié)點的子結(jié)點
    • 當(dāng)前一層搜索完畢后,轉(zhuǎn)入遍歷下一層中最左邊的結(jié)點
    • 最下層最右端是最末結(jié)點(即該結(jié)點深度最大,且在當(dāng)前層次的最右端)

要點

  • 當(dāng)樹的寬度大于深度時,該搜索算法較優(yōu)
  • 進行樹的遍歷時,使用隊列存儲樹的信息
    • 原因是:使用隊列比深度優(yōu)先搜索更為內(nèi)存密集
    • 由于需要存儲指針,隊列需要占用更多內(nèi)存

時間復(fù)雜度

  • O(|E| + |V|)查找:廣度優(yōu)先搜索:O(|E| + |V|)
  • E 是邊的數(shù)目
  • V 是頂點的數(shù)目

深度優(yōu)先搜索

定義

  • 一種在樹(或圖)中進行搜索的算法,從根結(jié)點開始,優(yōu)先按照樹的深度進行搜索
    • 從左邊開始一直往下遍歷樹的結(jié)點,直到不能繼續(xù)這一操作
    • 一旦到達某一分支的最末端,將返回上一結(jié)點并遍歷該分支的右子結(jié)點,如果可以將從左往右遍歷子結(jié)點
    • 當(dāng)前這一分支搜索完畢后,轉(zhuǎn)入根節(jié)點的右子結(jié)點,然后不斷遍歷左子節(jié)點,直到到達最底端
    • 最右的結(jié)點是最末結(jié)點(即所有祖先中最右的結(jié)點)

要點

  • 當(dāng)樹的深度大于寬度時,該搜索算法較優(yōu)
  • 利用堆棧將結(jié)點壓棧
    • 因為堆棧是“后進先出”的數(shù)據(jù)結(jié)構(gòu),所以無需跟蹤結(jié)點的指針。與廣度優(yōu)先搜索相比,它對內(nèi)存的要求不高。
    • 一旦不能向左繼續(xù)遍歷,則對棧進行操作

時間復(fù)雜度

  • O(|E| + |V|)查找:深度優(yōu)先搜索:O(|E| + |V|)
  • E 是邊的數(shù)目
  • V 是結(jié)點的數(shù)目

廣度優(yōu)先搜索 VS. 深度優(yōu)先搜索

  • 這一問題最簡單的回答就是,選取何種算法取決于樹的大小和形態(tài)
    • 就寬度而言,較淺的樹適用廣度優(yōu)先搜索
    • 就深度而言,較窄的樹適用深度優(yōu)先搜索

細微的區(qū)別

  • 由于廣度優(yōu)先搜索(BFS)使用隊列來存儲結(jié)點的信息和它的子結(jié)點,所以需要用到的內(nèi)存可能超過當(dāng)前計算機可提供的內(nèi)存(不過其實你不必擔(dān)心這一點)
  • 如果要在某一深度很大的樹中使用深度優(yōu)先搜索(DFS),其實在搜索中大可不必走完全部深度。可在 xkcd 上查看更多相關(guān)信息。
  • 廣度優(yōu)先搜索趨于一種循環(huán)算法。
  • 深度優(yōu)先搜索趨于一種遞歸算法

三、高效排序基礎(chǔ)

歸并排序

定義

  • 一種基于比較的排序算法
    • 將整個數(shù)據(jù)集劃分成至多有兩個數(shù)的分組
    • 依次比較每個數(shù)字,將最小的數(shù)移動到每對數(shù)的左邊
    • 一旦所有的數(shù)對都完成排序,則開始比較最左兩個數(shù)對中的最左元素,形成一個含有四個數(shù)的有序集合,其中最小數(shù)在最左邊,最大數(shù)在最右邊
    • 重復(fù)上述過程,直到歸并成只有一個數(shù)據(jù)集

要點

  • 這是最基礎(chǔ)的排序算法之一
  • 必須理解:首先將所有數(shù)據(jù)劃分成盡可能小的集合,再作比較

時間復(fù)雜度

  • O(n)最好的情況:歸并排序:O(n)
  • 平均情況:歸并排序:O(n log n)
  • 最壞的情況:歸并排序:O(n log n)

快速排序

定義

  • 一種基于比較的排序算法
    • 通過選取平均數(shù)將整個數(shù)據(jù)集劃分成兩部分,并把所有小于平均數(shù)的元素移動到平均數(shù)左邊
    • 在左半部分重復(fù)上述操作,直到左邊部分的排序完成后,對右邊部分執(zhí)行相同的操作
  • 計算機體系結(jié)構(gòu)支持快速排序過程

要點

  • 盡管快速排序與許多其他排序算法有相同的時間復(fù)雜度(有時會更差),但通常比其他排序算法執(zhí)行得更快,例如歸并排序。
  • 必須理解:不斷通過平均數(shù)將數(shù)據(jù)集對半劃分,直到所有的數(shù)據(jù)都完成排序

時間復(fù)雜度

  • O(n)最好的情況:歸并排序:O(n)
  • O(n log n)平均情況:歸并排序:O(n log n)
  • 最壞的情況:歸并排序:O(n2)

冒泡排序

定義

  • 一種基于比較的排序算法
    • 從左往右重復(fù)對數(shù)字進行兩兩比較,把較小的數(shù)移到左邊
    • 重復(fù)上述步驟,直到不再把元素左移

要點

  • 盡管這一算法很容易實現(xiàn),卻是這三種排序方法中效率最低的
  • 必須理解:每次向右移動一位,比較兩個元素,并把較小的數(shù)左移

時間復(fù)雜度

  • O(n)最好的情況:歸并排序:O(n)
  • O(n2)平均情況:歸并排序: O(n2)
  • O(n2)最壞的情況:歸并排序: O(n2)

歸并排序 VS. 快速排序

  • 在實踐中,快速排序執(zhí)行速率更快
  • 歸并排序首先將集合劃分成最小的分組,在對分組進行排序的同時,遞增地對分組進行合并
  • 快速排序不斷地通過平均數(shù)劃分集合,直到集合遞歸地有序

四、算法類型基礎(chǔ)

遞歸算法

定義

  • 在定義過程中調(diào)用其本身的算法
    • 遞歸事件:用于觸發(fā)遞歸的條件語句
    • 基本事件:用于結(jié)束遞歸的條件語句

要點

  • 堆棧級過深和棧溢出
    • 如果在遞歸算法中見到上述兩種情況中的任一個,那就糟糕了
    • 那就意味著因為算法錯誤,或者問題規(guī)模太過龐大導(dǎo)致問題解決前 RAM 已耗盡,從而基本事件從未被觸發(fā)
    • 必須理解:不論基本事件是否被觸發(fā),它在遞歸中都不可或缺
    • 通常用于深度優(yōu)先搜索

迭代算法

定義

  • 一種被重復(fù)調(diào)用有限次數(shù)的算法,每次調(diào)用都是一次迭代
    • 通常用于數(shù)據(jù)集中遞增移動

要點

  • 通常迭代的形式為循環(huán)、for、while和until語句
  • 把迭代看作是在集合中依次遍歷每個元素
  • 通常用于數(shù)組的遍歷

遞歸 VS. 迭代

  • 由于遞歸和迭代可以相互實現(xiàn),兩者之間的區(qū)別很難清晰地界定。但必須知道:
    • 通常遞歸的表意性更強,更易于實現(xiàn)
    • 迭代占用的內(nèi)存更少
  • (i.e. Haskell)函數(shù)式語言趨向于使用遞歸(如 Haskell 語言)
  • 命令式語言趨向于使用迭代(如 Ruby 語言)
  • 點擊 Stack Overflow post 了解更多詳情

遍歷數(shù)組的偽代碼(這就是為什么使用迭代的原因)

Recursion | Iteration

----------------------------------|----------------------------------

recursive method (array, n) | iterative method (array)

if array[n] is not nil | for n from 0 to size of array

print array[n] | print(array[n])

recursive method(array, n+1) |

else |

exit loop

貪婪算法

定義

  • 一種算法,在執(zhí)行的同時只選擇滿足某一條件的信息
  • 通常包含5個部分,摘自維基百科:
    • 候選集,從該集合中可得出解決方案
    • 選擇函數(shù),該函數(shù)選取要加入解決方案中的最優(yōu)候選項
    • 可行性函數(shù),該函數(shù)用于決策某一候選項是否有助于解決方案
    • 目標(biāo)函數(shù),該函數(shù)為解決方案或部分解賦值
    • 解決方案函數(shù),該函數(shù)將指明完整的解決方案

要點

  • 用于找到預(yù)定問題的最優(yōu)解
  • 通常用于只有少部分元素能滿足預(yù)期結(jié)果的數(shù)據(jù)集合
  • 通常貪婪算法可幫助一個算法降低時間 復(fù)雜度

偽代碼:用貪婪算法找到數(shù)組中任意兩個數(shù)字間的最大差值

greedy algorithm (array)

var largest difference = 0

var new difference = find next difference (array[n], array[n+1])

largest difference = new difference if new difference is > largest difference

repeat above two steps until all differences have been found

return largest difference

這一算法無需比較所有數(shù)字兩兩之間的差值,省略了一次完整迭代。

以下是Big O 核對表

Legend

Excellent

Good

Fair

Bad

Horrible

Data Structure Operations

Data Structure

Time Complexity

?

?

?

?

?

?

?

Space Complexity

?

Average

?

?

?

Worst

?

?

?

Worst

?

Access

Search

Insertion

Deletion

Access

Search

Insertion

Deletion

?

Array

O(1)

O(n)

O(n)

O(n)

O(1)

O(n)

O(n)

O(n)

O(n)

Stack

O(n)

O(n)

O(1)

O(1)

O(n)

O(n)

O(1)

O(1)

O(n)

Singly-Linked List

O(n)

O(n)

O(1)

O(1)

O(n)

O(n)

O(1)

O(1)

O(n)

Doubly-Linked List

O(n)

O(n)

O(1)

O(1)

O(n)

O(n)

O(1)

O(1)

O(n)

Skip List

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(n)

O(n)

O(n)

O(n)

O(n log(n))

Hash Table

-

O(1)

O(1)

O(1)

-

O(n)

O(n)

O(n)

O(n)

Binary Search Tree

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(n)

O(n)

O(n)

O(n)

O(n)

Cartesian Tree

-

O(log(n))

O(log(n))

O(log(n))

-

O(n)

O(n)

O(n)

O(n)

B-Tree

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(n)

Red-Black Tree

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(n)

Splay Tree

-

O(log(n))

O(log(n))

O(log(n))

-

O(log(n))

O(log(n))

O(log(n))

O(n)

AVL Tree

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(n)

Array Sorting Algorithms

Algorithm

Time Complexity

?

?

Space Complexity

?

Best

Average

Worst

Worst

Quicksort

O(n log(n))

O(n log(n))

O(n^2)

O(log(n))

Mergesort

O(n log(n))

O(n log(n))

O(n log(n))

O(n)

Timsort

O(n)

O(n log(n))

O(n log(n))

O(n)

Heapsort

O(n log(n))

O(n log(n))

O(n log(n))

O(1)

Bubble Sort

O(n)

O(n^2)

O(n^2)

O(1)

Insertion Sort

O(n)

O(n^2)

O(n^2)

O(1)

Selection Sort

O(n^2)

O(n^2)

O(n^2)

O(1)

Shell Sort

O(n)

O((nlog(n))^2)

O((nlog(n))^2)

O(1)

Bucket Sort

O(n+k)

O(n+k)

O(n^2)

O(n)

Radix Sort

O(nk)

O(nk)

O(nk)

O(n+k)

Graph Operations

Node / Edge Management

Storage

Add Vertex

Add Edge

Remove Vertex

Remove Edge

Query

Adjacency list

O(|V|+|E|)

O(1)

O(1)

O(|V| + |E|)

O(|E|)

O(|V|)

Incidence list

O(|V|+|E|)

O(1)

O(1)

O(|E|)

O(|E|)

O(|E|)

Adjacency matrix

O(|V|^2)

O(|V|^2)

O(1)

O(|V|^2)

O(1)

O(1)

Incidence matrix

O(|V| ? |E|)

O(|V| ? |E|)

O(|V| ? |E|)

O(|V| ? |E|)

O(|V| ? |E|)

O(|E|)

Heap Operations

Type

Time Complexity

?

?

?

?

?

?

?

Heapify

Find Max

Extract Max

Increase Key

Insert

Delete

Merge

Linked List (sorted)

-

O(1)

O(1)

O(n)

O(n)

O(1)

O(m+n)

Linked List (unsorted)

-

O(n)

O(n)

O(1)

O(1)

O(1)

O(1)

Binary Heap

O(n)

O(1)

O(log(n))

O(log(n))

O(log(n))

O(log(n))

O(m+n)

Binomial Heap

-

O(1)

O(log(n))

O(log(n))

O(1)

O(log(n))

O(log(n))

Fibonacci Heap

-

O(1)

O(log(n))

O(1)

O(1)

O(log(n))

O(1)

Big-O Complexity Chart

?

計算機科學(xué)中最重要的32個算法

  • A* 搜索算法——圖形搜索算法,從給定起點到給定終點計算出路徑。其中使用了一種啟發(fā)式的估算,為每個節(jié)點估算通過該節(jié)點的最佳路徑,并以之為各個地點排定次序。算法以得到的次序訪問這些節(jié)點。因此,A*搜索算法是最佳優(yōu)先搜索的范例。
  • 集束搜索(又名定向搜索,Beam Search)——最佳優(yōu)先搜索算法的優(yōu)化。使用啟發(fā)式函數(shù)評估它檢查的每個節(jié)點的能力。不過,集束搜索只能在每個深度中發(fā)現(xiàn)最前面的m個最符合條件的節(jié)點,m是固定數(shù)字——集束的寬度。
  • 二分查找(Binary Search)——在線性數(shù)組中找特定值的算法,每個步驟去掉一半不符合要求的數(shù)據(jù)。
  • 分支界定算法(Branch and Bound)——在多種最優(yōu)化問題中尋找特定最優(yōu)化解決方案的算法,特別是針對離散、組合的最優(yōu)化。
  • Buchberger算法——一種數(shù)學(xué)算法,可將其視為針對單變量最大公約數(shù)求解的歐幾里得算法和線性系統(tǒng)中高斯消元法的泛化。
  • 數(shù)據(jù)壓縮——采取特定編碼方案,使用更少的字節(jié)數(shù)(或是其他信息承載單元)對信息編碼的過程,又叫來源編碼。
  • Diffie-Hellman密鑰交換算法——一種加密協(xié)議,允許雙方在事先不了解對方的情況下,在不安全的通信信道中,共同建立共享密鑰。該密鑰以后可與一個對稱密碼一起,加密后續(xù)通訊。
  • Dijkstra算法——針對沒有負值權(quán)重邊的有向圖,計算其中的單一起點最短算法。
  • 離散微分算法(Discrete differentiation)
  • 動態(tài)規(guī)劃算法(Dynamic Programming)——展示互相覆蓋的子問題和最優(yōu)子架構(gòu)算法
  • 歐幾里得算法(Euclidean algorithm)——計算兩個整數(shù)的最大公約數(shù)。最古老的算法之一,出現(xiàn)在公元前300前歐幾里得的《幾何原本》。
  • 期望-最大算法(Expectation-maximization algorithm,又名EM-Training)——在統(tǒng)計計算中,期望-最大算法在概率模型中尋找可能性最大的參數(shù)估算值,其中模型依賴于未發(fā)現(xiàn)的潛在變量。EM在兩個步驟中交替計算,第一步是計算期望,利用對隱藏變量的現(xiàn)有估計值,計算其最大可能估計值;第二步是最大化,最大化在第一步上求得的最大可能值來計算參數(shù)的值。
  • 快速傅里葉變換(Fast Fourier transform,FFT)——計算離散的傅里葉變換(DFT)及其反轉(zhuǎn)。該算法應(yīng)用范圍很廣,從數(shù)字信號處理到解決偏微分方程,到快速計算大整數(shù)乘積。
  • 梯度下降(Gradient descent)——一種數(shù)學(xué)上的最優(yōu)化算法。
  • 哈希算法(Hashing)
  • 堆排序(Heaps)
  • Karatsuba乘法——需要完成上千位整數(shù)的乘法的系統(tǒng)中使用,比如計算機代數(shù)系統(tǒng)和大數(shù)程序庫,如果使用長乘法,速度太慢。該算法發(fā)現(xiàn)于1962年。
  • LLL算法(Lenstra-Lenstra-Lovasz lattice reduction)——以格規(guī)約(lattice)基數(shù)為輸入,輸出短正交向量基數(shù)。LLL算法在以下公共密鑰加密方法中有大量使用:背包加密系統(tǒng)(knapsack)、有特定設(shè)置的RSA加密等等。
  • 最大流量算法(Maximum flow)——該算法試圖從一個流量網(wǎng)絡(luò)中找到最大的流。它優(yōu)勢被定義為找到這樣一個流的值。最大流問題可以看作更復(fù)雜的網(wǎng)絡(luò)流問題的特定情況。最大流與網(wǎng)絡(luò)中的界面有關(guān),這就是最大流-最小截定理(Max-flow min-cut theorem)。Ford-Fulkerson 能找到一個流網(wǎng)絡(luò)中的最大流。
  • 合并排序(Merge Sort)
  • 牛頓法(Newton's method)——求非線性方程(組)零點的一種重要的迭代法。
  • Q-learning學(xué)習(xí)算法——這是一種通過學(xué)習(xí)動作值函數(shù)(action-value function)完成的強化學(xué)習(xí)算法,函數(shù)采取在給定狀態(tài)的給定動作,并計算出期望的效用價值,在此后遵循固定的策略。Q-leanring的優(yōu)勢是,在不需要環(huán)境模型的情況下,可以對比可采納行動的期望效用。
  • 兩次篩法(Quadratic Sieve)——現(xiàn)代整數(shù)因子分解算法,在實踐中,是目前已知第二快的此類算法(僅次于數(shù)域篩法Number Field Sieve)。對于110位以下的十位整數(shù),它仍是最快的,而且都認為它比數(shù)域篩法更簡單。
  • RANSAC——是“RANdom SAmple Consensus”的縮寫。該算法根據(jù)一系列觀察得到的數(shù)據(jù),數(shù)據(jù)中包含異常值,估算一個數(shù)學(xué)模型的參數(shù)值。其基本假設(shè)是:數(shù)據(jù)包含非異化值,也就是能夠通過某些模型參數(shù)解釋的值,異化值就是那些不符合模型的數(shù)據(jù)點。
  • RSA——公鑰加密算法。首個適用于以簽名作為加密的算法。RSA在電商行業(yè)中仍大規(guī)模使用,大家也相信它有足夠安全長度的公鑰。
  • Sch?nhage-Strassen算法——在數(shù)學(xué)中,Sch?nhage-Strassen算法是用來完成大整數(shù)的乘法的快速漸近算法。其算法復(fù)雜度為:O(N log(N) log(log(N))),該算法使用了傅里葉變換。
  • 單純型算法(Simplex Algorithm)——在數(shù)學(xué)的優(yōu)化理論中,單純型算法是常用的技術(shù),用來找到線性規(guī)劃問題的數(shù)值解。線性規(guī)劃問題包括在一組實變量上的一系列線性不等式組,以及一個等待最大化(或最小化)的固定線性函數(shù)。
  • 奇異值分解(Singular value decomposition,簡稱SVD)——在線性代數(shù)中,SVD是重要的實數(shù)或復(fù)數(shù)矩陣的分解方法,在信號處理和統(tǒng)計中有多種應(yīng)用,比如計算矩陣的偽逆矩陣(以求解最小二乘法問題)、解決超定線性系統(tǒng)(overdetermined linear systems)、矩陣逼近、數(shù)值天氣預(yù)報等等。
  • 求解線性方程組(Solving a system of linear equations)——線性方程組是數(shù)學(xué)中最古老的問題,它們有很多應(yīng)用,比如在數(shù)字信號處理、線性規(guī)劃中的估算和預(yù)測、數(shù)值分析中的非線性問題逼近等等。求解線性方程組,可以使用高斯—約當(dāng)消去法(Gauss-Jordan elimination),或是柯列斯基分解( Cholesky decomposition)。
  • Strukturtensor算法——應(yīng)用于模式識別領(lǐng)域,為所有像素找出一種計算方法,看看該像素是否處于同質(zhì)區(qū)域( homogenous region),看看它是否屬于邊緣,還是是一個頂點。
  • 合并查找算法(Union-find)——給定一組元素,該算法常常用來把這些元素分為多個分離的、彼此不重合的組。不相交集(disjoint-set)的數(shù)據(jù)結(jié)構(gòu)可以跟蹤這樣的切分方法。合并查找算法可以在此種數(shù)據(jù)結(jié)構(gòu)上完成兩個有用的操作:
      • 查找:判斷某特定元素屬于哪個組。
      • 合并:聯(lián)合或合并兩個組為一個組。
  • 維特比算法(Viterbi algorithm)——尋找隱藏狀態(tài)最有可能序列的動態(tài)規(guī)劃算法,這種序列被稱為維特比路徑,其結(jié)果是一系列可以觀察到的事件,特別是在隱藏的Markov模型中。
  • 現(xiàn)實中算法

    Linux內(nèi)核中的基本數(shù)據(jù)結(jié)構(gòu)和算法

  • 鏈表、雙向鏈表和無鎖鏈表
  • B+ 樹,代碼中的注釋將會告訴你一些教科書中不能學(xué)到的內(nèi)容:

    這是一個簡單的B+樹實現(xiàn),我寫它的目的是作為練習(xí),并以此了解B+樹的工作原理。結(jié)果該實現(xiàn)發(fā)揮了它的實用價值。

    ...

    一個不經(jīng)常在教科書中提及的技巧:最小值應(yīng)該放在右側(cè),而不是左側(cè)。一個節(jié)點內(nèi)所有被使用的槽位應(yīng)該在左側(cè),沒有使用的節(jié)點應(yīng)該為NUL,大部分的操作只遍歷一次所有的槽位,在第一個NUL處終止。

  • 帶權(quán)重的有序列表用于互斥鎖、驅(qū)動等;

  • 紅黑樹用于調(diào)度、虛擬內(nèi)存管理、跟蹤文件描述符和目錄條目等;
  • 區(qū)間樹
  • Radix樹,用于內(nèi)存管理、NFS相關(guān)查找和網(wǎng)絡(luò)相關(guān)的功能;

    radix樹的一個常見的用法是保存頁面結(jié)構(gòu)體的指針;

  • 優(yōu)先級堆,文字上的描述,主要是在教科書中實現(xiàn),用于control group系統(tǒng);

    包含指針的只允許簡單插入的靜態(tài)大小優(yōu)先級堆,基于CLR(算法導(dǎo)論)第七章

  • 哈希函數(shù),引用Knuth和他的一篇論文:

    Knuth建議選擇與機器字長所能表達的最大整數(shù)約成黃金比例的素數(shù)來做乘法散列,Chuck Lever 證實了這個技術(shù)的有效性;

    http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf

    這些選擇的素數(shù)是位稀疏的,也就是說對他們的操作可以使用位移和加法來替換機器中很慢的乘法操作;

  • 有些代碼,比如這個驅(qū)動,他們是自己實現(xiàn)的哈希函數(shù)

  • 哈希表,用于實現(xiàn)索引節(jié)點、文件系統(tǒng)完整性檢查等;
  • 位數(shù)組,用于處理flags、中斷等,在Knuth第四卷中有對其特性的描述;
  • Semaphores 和 spin locks
  • 二叉樹搜索用于中斷處理、登記緩存查找等;
  • 使用B-樹進行二叉樹查找;
  • 深度優(yōu)先搜索和他的變體被應(yīng)用于目錄配置;

    在命名空間樹中執(zhí)行一個修改過的深度優(yōu)先算法,開始(和終止于)start_handle所確定的節(jié)點。當(dāng)與參數(shù)匹配的節(jié)點被發(fā)現(xiàn)以后,回調(diào)函數(shù)將會被調(diào)用。如果回調(diào)函數(shù)返回一個非空的值,搜索將會立即終止,這個值將會回傳給調(diào)用函數(shù);

  • 廣度優(yōu)先搜索用于在運行時檢查鎖的正確性;
  • 鏈表上的合并排序用于垃圾回收、文件系統(tǒng)管理等;
  • 在某個驅(qū)動程序的庫函數(shù)里,冒泡排序居然也被實現(xiàn)了
  • Knuth-Morris-Pratt 字符串匹配;

    Knuth、Morris和 Pratt [1]實現(xiàn)了一個線性時間復(fù)雜度字符串匹配算法。該算法完全規(guī)避了對轉(zhuǎn)換函數(shù)DELTA的顯式計算。其匹配時間為O(n)(其中n是文本長度),只使用一個輔助函數(shù)PI[1...m](其中m是模式的長度),模式的預(yù)處理時間是O(m)。PI這個數(shù)組允許DELTA函數(shù)在需要時能迅速運行。大體上,對任意狀態(tài)q=0,1,...,m和任意SIGMA中的字符"a",PI["q"]保存了獨立于"a"的信息,并用于計算DELTA("q", "a")。由于PI這個數(shù)組只包含m個條目,而DELTA包含O(m|SIGMA|)個條目,我們通過計算PI進而在預(yù)處理時間保存|SIGMA|的系數(shù),而非計算DELTA。

    [1] Cormen, Leiserson, Rivest, Stein Introdcution to Algorithms, 2nd Edition, MIT Press

    [2] See finite automation theory

  • Boyer-Moore模式匹配,如下是引用和對其他算法的使用建議;

    Boyer-Moore字符串匹配算法:

    [1] A Fast String Searching Algorithm, R.S. Boyer and Moore. Communications of the Association for Computing Machinery, 20(10), 1977, pp. 762-772. http://www.cs.utexas.edu/users/moore/publications/fstrpos.pdf

    [2] Handbook of Exact String Matching Algorithms, Thierry Lecroq, 2004 http://www-igm.univ-mlv.fr/~lecroq/string/string.pdf

    注意:由于Boyer-Moore(BM)自右向左做匹配,有一種可能性是一個匹配分布在不同的塊中,這種情況下是不能找到任何匹配的。

    如果你想確保這樣的事情不會發(fā)生,使用Knuth-Pratt-Morris(KMP)算法來替代。也就是說,根據(jù)你的設(shè)置選擇合適的字符串查找算法。

    如果你使用文本搜索架構(gòu)來過濾、網(wǎng)絡(luò)入侵檢測(NIDS)或者任何安全為目的,那么選擇KMP。如果你關(guān)乎性能,比如你在分類數(shù)據(jù)包,并應(yīng)用服務(wù)質(zhì)量(QoS)策略,并且你不介意可能需要在分布在多個片段中匹配,然后就選擇BM。

  • Chromium 瀏覽器中的數(shù)據(jù)結(jié)構(gòu)和算法

  • 伸展樹

    此樹會被分配策略參數(shù)化,這個策略負責(zé)在C的自由存儲空間和區(qū)域中分配列表,參見zone.h

  • Demo中使用了Voronoi圖
  • 基于Bresenham算法的標(biāo)簽管理
  • 同時,代碼中還包含了一些第三方的算法和數(shù)據(jù)結(jié)構(gòu),例如:

  • 二叉樹
  • 紅黑樹
  • AVL樹
  • 用于壓縮的Rabin-Karp字符串匹配
  • 計算自動機的后綴
  • 蘋果實現(xiàn)的布隆過濾器
  • 布氏算法
  • 編程語言類庫

  • C++ STL,包含的有列表、堆、棧、向量、排序、搜索和堆操作算法
  • Java API 非常廣泛,包含的太多
  • Boost C++ 類庫,包含了諸如Boyer-Moore和Knuth-Morris-Pratt字符串匹配算法等;
  • 分配和調(diào)度算法

  • 最近最少使用算法有多種實現(xiàn)方式,在Linux內(nèi)核中是基于列表實現(xiàn)的;
  • 其他可能需要了解的是先入先出、最不常用和輪詢;
  • VAX、VMS系統(tǒng)中大量使用FIFO的變體;
  • Richard Carr的時鐘算法被用于Linux中頁面幀替換;
  • Intel i860處理器中使用了隨機替換策略;
  • 自適應(yīng)緩存替換被用于一些IBM的存儲控制中,由于專利原因在PostgreSQL只有簡單的應(yīng)用;
  • Knuth在TAOCP第一卷中提到的伙伴內(nèi)存分配算法被用于Linux內(nèi)核中,FreeBSD和Facebook都在使用jemalloc并發(fā)分配器;
  • *nix系統(tǒng)中的核心組件

  • grep和awk都實現(xiàn)了使用Thompson-McNaughton-Yamada構(gòu)建算法實現(xiàn)從正則表達式中創(chuàng)建NFA
  • tsort實現(xiàn)了拓撲排序
  • fgrep實現(xiàn)了Aho-Corasick 字符串匹配算法;
  • GNU grep,據(jù)作者Mike Haertel所說,實現(xiàn)了Boyer-Moore算法;
  • Unix中的crypt(1)實現(xiàn)了啞謎機(Enigma Machine)中的加密算法的變種;
  • Doug Mcllroy基于和James合作的原型實現(xiàn)的Unix diff,比用來計算Levenshtein距離的標(biāo)準(zhǔn)動態(tài)規(guī)劃算法更好,Linux版本被用來計算最短編輯距離;
  • 加密算法

  • Merkle樹,尤其是Tiger Tree Hash的變種,用于點對點的程序,例如GTK Gnutella 和LimeWire;
  • MD5用于為軟件包提供校驗碼,還用于*nix系統(tǒng)(Linux實現(xiàn))中的完整性校驗,同時他還支持Windows和OS X系統(tǒng);
  • OpenSSL實現(xiàn)了需要加密算法,諸如AES,Blowfish,DES,SHA-1,SHA-2,RSA,DES等;
  • 編譯器

  • yacc和bison實現(xiàn)了LALR解析器
  • 支配算法用于基于SSA形式的最優(yōu)化編譯器;
  • lex和flex將正則表達式編譯為NFA;
  • 壓縮和圖片處理

  • 為GIF圖片格式而出現(xiàn)的Lempel-Zivsraf算法在圖片處理程序中經(jīng)常被應(yīng)用,從一個簡單的*nix組件轉(zhuǎn)化為一個復(fù)雜的程序;

  • 運行長度編碼被用于生成PCX文件(用于Paintbrush這個程序中),壓縮BMP文件和TIFF文件;

  • 小波壓縮(Wavelet壓縮)是JPEG 2000的基礎(chǔ),所以所有生成JPEG 2000文件的數(shù)碼相機都是實現(xiàn)了這個算法;

  • Reed-Solomon糾錯用于Linux內(nèi)核、CD驅(qū)動、條形碼讀取,并且結(jié)合卷積從航行團隊進行圖片傳輸;

  • 沖突驅(qū)動條款學(xué)習(xí)算法(Conflict Driven Clause Learning)

    自2000年以來,在工業(yè)標(biāo)準(zhǔn)中的SAT(布爾滿足性問題)求解器的運行時間每年都在成倍減少。這一發(fā)展的一個非常重要的原因是沖突驅(qū)動條款學(xué)習(xí)算法(Conflict Driven Clause Learning)的使用,它結(jié)合了Davis Logemann和Loveland的約束編程和人工智能研究技術(shù)的原始論文中關(guān)于布爾約束傳播的算法。具體來說,工業(yè)建模中SAT被認為是一個簡單的問題(見討論)。對我來說,這是近代最偉大的成功故事之一,因為它結(jié)合了先進的算法、巧妙的設(shè)計思路、實驗反饋,并以一致的共同努力來解決這個問題。Malik和Zhang的CACM論文是一個很好的閱讀材料。許多大學(xué)都在教授這個算法,但通常是在邏輯或形式化方法的課程中。

    ?

    ?


    希望對您企業(yè)應(yīng)用開發(fā)與企業(yè)信息化有幫助。 其它您可能感興趣的文章:

    《視覺直觀感受 7 種常用的排序算法》

    《匈牙利 Sapientia 大學(xué)的 6 種排序算法舞蹈視頻》

    《視頻:6 分鐘演示 15 種排序算法》

    《SORTING:可視化展示排序算法的原理,支持單步查看》

    《VisuAlgo:通過動畫學(xué)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)》

    軟件開發(fā)的專業(yè)化
    IT基礎(chǔ)架構(gòu)規(guī)劃方案一(網(wǎng)絡(luò)系統(tǒng)規(guī)劃)
    IT基礎(chǔ)架構(gòu)規(guī)劃方案二(計算機系統(tǒng)與機房規(guī)劃規(guī)劃)?
    IT基礎(chǔ)架構(gòu)規(guī)劃方案三(IT基礎(chǔ)軟件和系統(tǒng)規(guī)劃)
    企業(yè)應(yīng)用之性能實時度量系統(tǒng)演變
    云計算參考架構(gòu)幾例
    智能移動導(dǎo)游解決方案簡介
    人力資源管理系統(tǒng)的演化

    如有想了解更多軟件研發(fā) , 系統(tǒng) IT集成 , 企業(yè)信息化 等資訊,請關(guān)注我的微信訂閱號:


    作者:Petter Liu
    出處:http://www.cnblogs.com/wintersun/
    本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
    該文章也同時發(fā)布在我的獨立博客中-Petter Liu Blog。

    轉(zhuǎn)載于:https://www.cnblogs.com/wintersun/p/4840585.html

    總結(jié)

    以上是生活随笔為你收集整理的数据结构与算法 Big O 备忘录与现实的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。