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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构与算法---笔记

發布時間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法---笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一章


1.1 計算

計算機只是我們的工具(手段),我們研究的對象是計算

計算 = 信息處理

借助某種工具,遵照一定規則,以明確而機械的形式進行。

機器模型 = 計算機 = 信息處理工具

所謂算法,即特定計算模型下,旨在解決特定問題的指令序列

  • 輸入,待處理的信息(問題)
  • 輸出,經處理的信息(答案)
  • 正確性,的確可以解決指定的問題
  • 確定性,任一算法都可以描述為一個由基本操作組成的序列
  • 可行性,每一基本操作都可實現,且在常數時間內完成
  • 有窮性,對于任何輸入,經有窮次基本操作,都可以得到輸出

好算法的定義

  • 正確,對于輸入有正確的輸出
  • 健壯,對于不合法的操作,可以恢復程序的正常執行
  • 可讀,結構化+準確命名+注釋+ ···
  • 效率,速度盡可能快,存儲空間盡可能少

程序 = 數據結構 + 算法

要改進或者優化某個算法,我們需要先知道這個算法的效率。

算法分析

  • 正確性,算法功能與問題要求是否一致
  • 成本,運行時間+所需存儲空間

通常我們對一個算法的度量值的大小都這個度量規模的最壞情況

對于特定問題+不同算法,我們該如何判斷其優劣呢?考察以下兩種模型

  • TM模型(圖靈機)。
  • RAM模型(匯編)。

我們度量的單位為CPU的執行次數,算法在必要的時候需要復位


大 O 記號

n為問題規模

常系數可忽略:

O(f(n))=O(c?f(n))O(f(n))=O(c?f(n))
低次項可忽略: O(na+nb)=O(na),a>b>0O(na+nb)=O(na),a>b>0

其他記號:

  • Big Ω,最大下界。
  • Big θ ,折中。

O的等級:

  • 常數,O(1)
  • 對數,O(logn),以2為底數
  • 多項式,O(n^c)
  • 線性復雜度,O(n)
  • 指數復雜度,O(2^n)

算法效率從O(2^n)到O(n^c)是一個難點。通常情況下,我們想找出一個效率從指數到多項式的算法是非常難的。這是一個分水嶺

定理:2-Subset is NP-complete。解釋:就目前的計算模型而言,不存在可在多項式時間內回答此問題的算法。

NP問題就是一個冪集問題,效率為O(2^n)。


算法分析

兩個主要任務 = 正確性( 不變性*單調性 ) + 復雜度

C++等高級語言的基本指令,均等效于RAM的基本指令;在漸進意義下,二者大體相當。

復雜度分析的主要方法:

  • 迭代:級數求和
    • 算術級數:與末項的平方同階
    • 冪方級數:比冪次高出一階
    • 幾何級數:與末項同階
    • 收斂級數:常數 O(1)(某種情況下是有意義的,比如迭代的去投擲一枚硬幣,直到出現正面)
    • 調和級數:O(logn)
    • 對數級數:O(nlogn)
    • …(有一本書叫做《具體數學》)
  • 遞歸:遞歸跟蹤 + 遞推方程
  • 猜想 + 驗證

迭代與遞歸

迭代乃人工,遞歸方神通

從效率上講,迭代效率比遞歸效率要來的高。我們需要學習的是從遞歸到迭代的一個過程。

凡治眾如治寡,分數是也

對于一個問題,分成一系列子問題。通過求解子問題進而得出這個問題的解。

減而治之與分而治之


動態規劃

第一個例子:斐波那契數列

遞歸版本的fib和迭代版的fib的效率相差巨大(原因重新計算已經被計算過的fib數)。

//遞歸版 int fib(int n){return (2>n)? n : fib(n-1) + fib(n-2); }

很明顯這是求解一個冪集問題,這段代碼時間復雜度是2的n次方,空間復雜度是O(n)。

改進1:記憶版本(制表)

//迭代 int arr[] = new int[n+1]; arr[1] = 1; arr[2] = 1; for(int i=3;i<n;i++){arr[i] = arr[i-1]+arr[i-2]; } return arr[n];

以上時間復雜度和空間復雜度都是O(n)。

改進2:動態規劃(自底而上)

//迭代 int f=0,g=1; while(0<n--){g = g+f;f = g-f; } return g;

時間復雜度是O(n),空間復雜度是O(1)。

第二個例子:LCS序列

遞歸版(算法步驟):
對于序列 A[0, n] 和 B[0, m] 無非三種情況

  • 若 n= -1 或 m= -1,則取作空序列(“”)
  • 若 A[n]= ‘X’ =B[n],則取作LCS( A[0,n), B[0,m) ) + ‘X’
  • A[n] != B[n],則在 LCS( A[0,n], B[0,m)) 與 LCS( A[0,n), B[0,m]) 中取更長者
  • public static String LCS(char A[],int alo,int ahi,char B[],int blo,int bhi){//第一種情況if(ahi==-1||bhi==-1){return "";}//第二種情況if(A[ahi]==B[bhi]){return LCS(A,alo,ahi-1,B,blo,bhi-1)+A[ahi];}//第三種情況,由于這種情況將問題分成2個子問題。else{String AA = LCS(A,alo,ahi-1,B,blo,bhi);String BB = LCS(A,alo,ahi,B,blo,bhi-1);return AA.length()>BB.length()? AA : BB;} }

    明顯是一個冪集問題,所以時間復雜度為O(2^n),空間復雜度為O(n)

    由遞歸分析,我們得出一個結論,重復元素多次計算,所以我們可以改進。

    迭代版(制表):

  • 第一行和第一列初始化為0
  • 若行和列所對應的字母相等,則table[i][j] = table[i-1][j-1]
  • table[i][j] 取 table[i-1][j] 和 table[i][j-1] 更大者
  • public static void main(String[] args) {//測試數據String A = "DATA";String B = "NAA";int n = A.length();int m = B.length();//start LCS//初始化int table[][] = new int[n+1][m+1];for(int i=0;i<n;i++){table[i][0] = 0;}for(int j=0;j<m;j++){table[0][j] = 0;}//迭代for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){//第二種情況,由于字符串是從0開始,而表格是從1開始,所以對于的table和字符串相差1if(A.charAt(i-1)==B.charAt(j-1)){table[i][j] = table[i-1][j-1]+1;}//第三種情況else{table[i][j] = table[i-1][j]>table[i][j-1] ? table[i-1][j] :table[i][j-1];}}}//end LCS//測試結果int count = 1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(table[i][j]==count){System.out.print(A.charAt(i-1));count++;}}}System.out.println();}

    顯然時間復雜度和空間復雜度都為O(n*m)

    總結

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

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