前端基礎系列(三) -- 演算法 + 資料結構基礎

weixin_33912445發表於2018-01-24

結構化程式設計

  1. 一行一行執行
  2. 有條件控制語句 if...else...
  3. 有迴圈控制語句 while(exp) do...

虛擬碼

流程圖

演算法

  1. 輸入:一個演算法必須有零個或以上輸入量。
  2. 輸出:一個演算法應有一個或以上輸出量,輸出量是演算法計算的結果。
  3. 明確性:演算法的描述必須無歧義,以保證演算法的實際執行結果是精確地 匹配要求或期望,通常要求實際執行結果是確定的。
  4. 有限性:依據圖靈的定義,一個演算法是能夠被任何圖靈完備系統模擬的一串運算,而圖靈機只有有限個狀態、有限個輸入符號和有限個轉移函式(指令)。而一些定義更規定演算法必須在有限個步驟內完成任務。
  5. 有效性:又稱可行性。能夠實現,演算法中描述的操作都是可以通過已經實現的基本運算執行有限次來實現。

資料結構

即資料的結構

雜湊(Hash)

鍵值對: { '鍵' : '值' } ==> Array / Object

  • 計數排序:計數排序使用一個額外的陣列 arrhash),其中第 i 個元素是待排序陣列 Arr 中值等於 i 的元素的個數。然後根據陣列 arr 來將 Arr 中的元素排到正確的位置(用到了桶,但是每個桶中只有相同的數字,空間浪費)(所有的桶是Hash,桶裡是佇列,先進先出)。
    複雜度:n + max
    缺點:
    1. 需要一個雜湊表示計數工具。
    2. 無法對小數和負數排序

  • 桶排序:將陣列分到有限數量的桶裡。每個桶再個別排序,此時可以用其他排序方法(所有的桶是Hash,桶裡是佇列,先進先出

  • 基數排序:只有十個桶(0 - 9),先排個位,之後十位,依次到最高位(所有的桶是Hash,桶裡是佇列,先進先出
    說明:比較排序的極限 n*logN

佇列(queue)

  • 特點:先進先出
  • 可以用陣列實現

棧(stack)

  • 特點:先進後出
  • 可以用陣列實現

連結串列(Linked List)

  • 是一種線性表,但是並不會按線性的順序儲存資料,而是在每一個節點裡存到下一個節點的指標(Pointer)。使用連結串列結構可以克服陣列連結串列需要預先知道資料大小的缺點,連結串列結構可以充分利用計算機記憶體空間,實現靈活的記憶體動態管理。但是連結串列失去了陣列隨機讀取的優點,同時連結串列由於增加了結點的指標域,空間開銷比較大

  • 陣列無法直接刪除中間的一項,但是連結串列可以,連結串列是動態陣列

  • Hash 實現連結串列,head 表示第一個 Hash ,所有的 Hash 都是節點(node

  • 是一種抽象資料型別(ADT)或是實作這種抽象資料型別的資料結構,用來模擬具有樹狀結構性質的資料集合。它是由n(n>0)個有限節點組成一個具有層次關係的集合

  • 特點

    1. 每個節點有零個或多個子節點
    2. 沒有父節點的節點稱為根節點
    3. 每一個非根節點有且只有一個父節點
    4. 除了根節點外,每個子節點可以分為多個不相交的子樹
  • 術語

    1. 節點的層次:從根開始定義起,根為第1層,根的子節點為第2層,以此類推;
    2. 深度:對於任意節點n,n的深度為從根到n的唯一路徑長,根的深度為0;
    3. 節點的度:一個節點含有的子樹的個數稱為該節點的度;
    4. 樹的度:一棵樹中,最大的節點的度稱為樹的度;
    5. 葉節點終端節點:度為零的節點;
  • 二叉樹(Binary tree):每個節點最多含有兩個子樹的樹稱為二叉樹

    1. 二叉樹的第 i 層至多擁有2的( i-1 )次冪個節點數
  • 完全二叉樹:對於一顆二叉樹,假設其深度為d(d>1)。除了第d層外,其它各層的節點數目均已達最大值,且第d層所有節點從左向右連續地緊密排列,這樣的二叉樹被稱為完全二叉樹

    1. 在一棵二叉樹中,除最後一層外,若其餘層都是滿的,並且最後一層或者是滿的,或者是在右邊缺少連續若干節點,則此二叉樹為完全二叉樹(Complete Binary Tree)

    2. 具有n個節點的完全二叉樹的深度為log以2為底n的對數+1。深度為k的完全二叉樹,至少有2的k次冪個節點,至多有2的( k+1 )次冪 - 1個節點

  • 滿二叉樹:所有葉節點都在最底層的完全二叉樹

    1. 一棵深度為k,且有2的( k+1 )次冪 - 1個節點的二叉樹,稱為滿二叉樹(Full Binary Tree)

    2. 每一層上的節點數都是最大節點數

說明:用陣列儲存滿二叉樹和完全二叉樹,用Hash儲存其他的樹

演算法和資料結構結合

  1. 我們要解決一個跟資料相關的問題
  2. 分析這個問題,想出對應的資料結構
  3. 分析資料結構,想出演算法
    資料結構和演算法是互相依存、不可分開的

分類:

  1. 分治法:把一個問題分割槽成互相獨立的多個部分分別求解的思路。這種求解思路帶來的好處之一是便於進行平行計算。前端主要使用分治法

  2. 動態規劃法:當問題的整體最優解就是由區域性最優解組成的時候,經常採用的一種方法

  3. 貪婪演算法:常見的近似求解思路。當問題的整體最優解不是(或無法證明是)由區域性最優解組成,且對解的最優性沒有要求的時候,可以採用的一種方法

  4. 線性規劃法:見詞條

  5. 簡併法:把一個問題通過邏輯或數學推理,簡化成與之等價或者近似的、相對簡單的模型,進而求解的方法

排序演算法

  • 氣泡排序:它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。
    這個演算法的名字由來是因為越大的元素會經由交換慢慢“浮”到數列的頂端,故名。
  • 選擇排序:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
  • 插入排序:通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在實現上,通常採用in-place排序(即只需用到的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,為最新元素提供插入空間。
  • 基數排序:將整數按位數切割成不同的數字,然後按每個位數分別比較。將所有待比較數值(正整數)統一為同樣的數位長度,數位較短的數前面補零。然後,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以後,數列就變成一個有序序列。
  • 快速排序:快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分為兩個子序列(sub-lists)。
    步驟為:
    1. 從數列中挑出一個元素,稱為"基準"(pivot),
    2. 重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面(相同的數可以到任何一邊)。在這個分割槽結束之後,該基準就處於數列的中間位置。這個稱為分割槽(partition)操作。
    3. 遞迴地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。
      遞迴到最底部時,數列的大小是零或一,也就是已經排序好了。這個演算法一定會結束,因為在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。

相關文章