1. 程式人生 > >【軟體設計師】資料結構與演算法

【軟體設計師】資料結構與演算法

陣列與矩陣

  • 陣列的儲存地址計算
    一維陣列a[n]:a[i]=a+i*len
    二維陣列a[m][n]:
        按行儲存:a[i][j]=a+(i*n+j)*len
        按列儲存:a[i][j]=a+(j*m+i)*len
    **a表示陣列a[0](第一個元素)所在位置,len表示單個元素所佔空間
  • 矩陣計算
    在矩陣中下標分別為i和j的元素,對應的一維陣列的下標計算公式:代入排除法
    上三角計算公式:(2n-i+1)*i/2+j,下三角計算公式:(i+1)*i/2+j

線性表

  • 順序表
  • 連結串列
  • 佇列:先進先出(兩端可以同時操作)
    迴圈佇列
        隊空條件:頭=尾
        隊滿條件:(尾+1)%總元素=頭
  • 棧:先進後出(只有一端可以操作)

廣義表

  • 長度:最外層包含的元素個數
  • 深度:包含括號的重數
  • 表頭head:第一個元素
  • 表尾tail:除第一個元素以外的所有元素
    若有:LS=(a,(b,c),(d,e)),則長度為3,深度為2
    head(LS)=a,tail(LS)=((b,c),(d,e))取出b字母:head(head(tail(LS)))

樹與二叉樹

  • 概念
    • 結點的度:子結點的個數
    • 樹的度:MAX(結點的度)
    • 葉子結點:沒有子結點
    • 內部結點:除去根結點和葉子結點
    • 兄弟結點:同一個父節點
    • 層次:根結點為第1層,依次排下來
  • 二叉樹的特性
    • 第i層上最多有2i-1個結點
    • 深度為K的二叉樹最多有2K-1個結點
    • 葉子結點數=度為2的結點數+1
  • 二叉樹的遍歷
    • 前序遍歷:根左右
    • 中序遍歷:左根右
    • 後序遍歷:左右根
    • 層次遍歷:從第一層的結點開始,從左到右依次往下訪問
  • 查詢二叉樹(排序二叉樹)
    • 左結點小於根,右結點大於根
  • 最優二叉樹(哈夫曼樹)
    • 權:葉子結點的數值
    • 帶權路徑長度:權值*路徑長度
  • 線索二叉樹
  • 平衡二叉樹:左右子樹的高度之差的絕對值≤1,並且左右子樹任是平衡二叉樹

  • 儲存
    • 鄰接矩陣:圖有N個結點就是NXN的矩陣,頂點i到頂點j有連線,矩陣對應的Rij就是1,否則就是0
    • 鄰接表:頂點與頂點的連線用連結串列示,用一維陣列順序儲存每個連結串列的頭指標
  • 遍歷
    • 深度優先:從上往下,一個支點搜尋到底
    • 廣度優先:按層搜尋,一層搜尋完再開始下一層
  • 拓撲排序:用一個序列來表達,一個圖當中那些事件可以先執行,那些可以後執行
  • 最小生成樹
    • 普里姆演算法:從一個結點出發,找距離最小的結點
    • 克魯斯卡爾演算法: 確定要選幾條邊,從最小的開始選,注意不要產生環路

排序與查詢

順序查詢:O(n)

二分查詢:向下取整,O(log2n)

散列表

演算法基礎及常見演算法

  • 分治法(歸併排序,最大子和段問題)基本思想:將一個難以直接解決的大問題分解成一些規模較小的相同問題,以便各個擊破,分而治之。
    • 如規模為n的問題可分解成k個子問題,1<k≤n,這些子問題互相獨立且與原問題相同。分治法產生的子問題往往是原問題的較小規模。
    • 步驟:
      • (1)分解:將原問題分解成一系列子問題。
      • (2)求解:遞迴地求解各個子問題。若子問題足夠小,則直接求解。
      • (3)合併:將子問題的解合併成原問題的解。
  • 動態規劃法(0-1揹包問題,最長公共子序列問題;尋找最優解)基本思想:將帶求解問題分解成若干個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。
    • 經分解得到的子問題往往不是獨立的,在過程當中,可以用一個表來記錄所有已解決的子問題的答案,不管該子問題以後是否被用到,只要它被計算過,就將其結果填入表中。
    • 步驟:
      • (1)找出最優解的性質,並刻畫其結構特徵;
      • (2)遞迴地定義最優解的值;
      • (3)以自底向上的方式計算出最優值;
      • (4)根據計算最優值時得到的資訊,構造一個最優解。
  • 貪心演算法(活動選擇,揹包問題):當前每一步都是最優的,是當前最好的選擇,但不一定是最優解。
  • 回溯法(0-1揹包,n皇后問題):