資料結構與演算法-複雜度分享&大 O 演算法

AllenBug 發表於2019-08-11

一. 大 O 表示法,分析時關注原則:

  • 只關注迴圈次數最多的一段程式碼
  • 加法原則:總複雜度等於量級最大那段程式碼複雜度
  • 乘法原則:巢狀程式碼的複雜度等於巢狀程式碼內外複雜度的乘積
    常見覆雜度

    二.線性表結構

    陣列

       陣列(Array)是一種線性表資料結構,它用一組連續的記憶體空間,來儲存一組具有相同型別的資料。如果你學習過 C 語言,應該對這段定義很熟悉,但是在 PHP 這種動態語言中,因為陣列底層是通過雜湊表(後面我們會介紹這個資料結構)實現的,所以功能異常強大,這段常規的陣列定義在 PHP 中並不成立,PHP 的陣列可以儲存任何型別資料,如果與 Java 對比的話,PHP 陣列整合了 Java 的陣列、List、Set、Map 於一身,所以寫程式碼的效率比 Java 高了幾個量級
       特性:拋開 PHP 或 JavaScript 這種動態語言,對於傳統的陣列,比如:C 語言和 Java 中的陣列,在使用之前都需要宣告陣列儲存資料的型別和陣列的大小,陣列的優點是可以通過下標值隨機訪問陣列內的任何元素,演算法複雜度是 O(1) ,非常高效,但是缺點是刪除/插入元素比較費勁。以刪除為例,需要在刪除某個元素後,將後續元素都往前移一位,如果是插入,則需要將插入位置後的元素都往後移,所以對陣列的插入/刪除而言,演算法複雜度是 O(n),當然了,這個針對 C/Java 這種語言而言,PHP 不受此約束,因為它不是傳統一樣的陣列。

    連結串列

      與陣列不同,連結串列並不需要一塊連續的記憶體空間,它通過“指標”將一組零散的記憶體塊串聯起來使用,如圖:

      單向連結串列:有兩個節點比較特殊,分別是第一個節點和最後一個節點。我們通常把第一個節點叫做頭節點,把最後一個節點叫做尾節點。其中,頭節點用來記錄連結串列的基地址,有了它,可以遍歷得到整條連結串列。而尾節點特殊的地方是:指標不是指向下一個節點,而是指向 NULL,表示這是連結串列的最後一個節點。對單連結串列而言,理論上來說,插入和刪除節點的時間複雜是O(1),查詢節點的時間複雜度是 O(n)。如圖:

      迴圈連結串列:迴圈連結串列和單連結串列的區別是尾節點執行的頭節點,從而頭尾相連,有點像貪吃蛇,可用於解決 [約瑟夫環] 問題,如圖:

      雙向連結串列: 與單連結串列的區別是雙向連結串列除了有一個指向下一個節點的指標外,還有一個用於指向上一個節點的指標,從而實現通過 O(1)複雜度找到上一個節點。正是因為這個節點,是的雙向連結串列的插入,刪除節點時比單連結串列更高效,雖然我們前面已經提到單連結串列插入,刪除時間複雜 O(1)了,但是這沒有考慮還只是針對插入,刪除本身而言。已刪除為例,刪除某個節點後,需要將其前驅節點的指標指向被刪除節點的下一個節點,這樣,我們還需要將獲取前驅節點,在單連結串列中獲取前驅節點的時間複雜度是O(n),所以綜合來看單連結串列的刪除,插入操作時間複雜度也是O(n),而雙向連結串列則不然,它有一個指標指向上一個節點,所以其插入和刪除時間複雜度才是正真的 O(1)。

       迴圈雙向連結串列:


相關文章

資料結構

樹狀資料結構儲存方式——查詢篇

鄰接列表模型在日常業務開發中,我們常常會碰見一些具有層次結構的樹狀資料。而在用關係型資料庫儲存時,往往將這種資料結構以一種稱為鄰接列表的模型進行儲存,像這樣:CREATE TABLE `categor
資料結構

樹狀資料結構儲存方式—— CUD 篇

前文簡單介紹了巢狀集合的資料模型,以及查詢的方法,傳送門: 樹狀資料結構儲存方式——查詢篇Create在巢狀集合模型中,每個資料其實就是一個節點 (node),而每個節點佔用2個位值,比如我們先新增一
資料結構|Go

理解 Golang 的 map 資料結構設計

定義golang 中的 map 就是常用的 hashtable,底層實現由 hmap,維護著若干個 bucket 陣列,通常每個 bucket 儲存著8組kv對,如果超過8個(發生hash衝突時),會
演算法

淺談滴滴派單演算法

本文作者:王犇 滴滴 | 首席演算法工程師導讀:說到滴滴的派單演算法,大家可能感覺到既神祕又好奇,從計程車揚召到司機在滴滴平臺搶單最後到平臺派單,大家今天的出行體驗已經發生了翻天覆地的變化,面對著
Python|演算法

python實現Dijkstra演算法之 最短路徑問題

從某源點到其餘各頂點的最短路徑  Dijkstra演算法可用於求解圖中某源點到其餘各頂點的最短路徑。假設G={V,{E}}是含有n個頂點的有向圖,以該圖中頂點v為源點,使用Dijkstra演算法求頂點
演算法

分散式技術原理與演算法解析-聶鵬程-極客時間-返現24元

極客時間出品的《分散式技術原理與演算法解析》由聶鵬程所作,聶鵬程是智載雲帆CTO,前華為分散式Lab資深技術專家。本專欄帶你12周精通分散式核心技術  。課程訂閱及價格:原價¥99 ,限時¥68  ,
演算法

分享一個權重隨機演算法

<?php\//權重隨機演算法排程\class WeightedRoundRobin\{\private static $_weightArray = array();\\private sta
演算法|PHP

手把手使用 PHP 實現 LRU 快取淘汰演算法

:pencil2:LRU(cache):hourglass:LRU介紹快取是一種提高資料讀取效能的技術。但是對於計算機來說,並不可能快取所有的資料,在達到它的臨界空間時,我們需要通過一些規則用新的資料
人工智慧|演算法

幽默:所有演算法現在都稱為AI - Eran Hammer

所有演算法現在都稱為AI回覆:1.現在,所有軟體開發人員都稱為軟體工程師。2.有時我想知道這是因為演算法變得更好了嗎?還是降低了構成智慧的門檻。3. 從歷史上來看,情況恰恰相反:每次發明“人工智慧”之
演算法

演算法筆記(廣度優先搜尋)

廣度優先搜尋指出是否有從 A 到 B 的路徑。如果有,廣度優先搜尋將找出最短路徑。面臨類似於尋找最短路徑的問題時,可嘗試使用圖來建立模型,再使用廣度優先搜尋來解決問題。有向圖中的邊為箭頭,箭頭的方向指
Python|演算法

Python之 常用查詢演算法:最小項搜尋、順序搜尋、二分搜尋

最小項搜尋  def min_search(items):  """  最小項搜尋  :param items:  :return:  """  min_index = 0  for i in ran
演算法

推薦!計算機視覺最適合入門的 8 本教程,演算法與實戰兼備

計算機視覺是人工智慧的一個分支,涉及理解數字影象的內容,如照片和視訊。深度學習在挑戰性的計算機視覺任務上取得了令人印象深刻的進展,並有望取得進一步的進展。快速熟悉這個領域的最好方法之一就是找一本關於這