1. 程式人生 > >演算法與資料結構簡介(一)

演算法與資料結構簡介(一)

演算法與資料結構簡介

為什麼學習演算法與資料結構?

  • 掌握常用的演算法和資料結構,可以提升程式碼的執行效率
  • 功利性目的,找到更好的工作
  • 喜歡上演算法,理解並運用它,在程式設計領域,擁有雄厚的“內功”

區塊鏈

區塊鏈就是演算法中的樹+單向連結串列
在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

如何有效學習演算法與資料結構

有一本書叫《異類—不一樣的成功啟示錄》,作者 馬爾科姆·格拉德威爾提出來:一萬個小時定律,以及精通一個領域所要做的3點內容

  1. 切碎知識點
  2. 刻意練習
  3. 反饋(LeetCode\GitHub看高手的程式碼)
    在這裡插入圖片描述

演算法的分類

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

切題四件套

  1. 明確題目意思
  2. 想好可能的解決方案
    (1)比較時間複雜度和空間複雜度
    (2)最佳解
  3. 多寫多練
  4. 測試

時間複雜度&&空間複雜度

在這裡插入圖片描述

在這裡插入圖片描述
階乘 >> 指數 >> 立方 >> 平方 >> 線性 >> 對數 >> 常數

O(n!)   O(2^n)   O(n^3)   O(n^2)   O(n)   O(log n)   O(1)
注意點:多種複雜度的情況,只看最高複雜度即可

O(1):

  int  n = 100;
  System.out.println("結果是:" + n);

O(1):

  int  n = 100;
  System.out.println("結果一是:" + n);
  System.out.println("結果二是:" + n);
  System.out.println("結果三是:" + n);

O(N):

  int n =100;
  for(int i = 1; i <= n; i++){
    System.out.println("結果是:" + i);
  }

O(N^2):

  int n =100;
  for(int i = 1; i <= n; i++){
     for(int j = 1; j <= n; j++){
        System.out.println("結果是:" + i + "&&" + j);
     }
   }

O(log(N)):

   int n =100;
   for(int i = 1; i < n; i * 2){
      System.out.println("結果是:" + i);
   }

O(2^N):

   int n =100;
   for(int i = 1; i <= Math.pow(2,n); i++){
       System.out.println("結果是:" + i);
   }

O(N!):

   int n =100;
   for(int i = 1; i <= factorial(n); i++){
       System.out.println("結果是:" + i);
   }

舉例說明

在這裡插入圖片描述S(n) = 1+2+3+…+n
S(n) = n+(n-1)+…+1
推匯出:2S(n) = n(n+1)
S(n) = n(n+1)/2 即等差數列S(n) = n(a1+an)/2 || Sn=n*a1+n(n-1)d/2

在這裡插入圖片描述斐波拉契公式,前兩項和等於後一項

在這裡插入圖片描述

從遞迴推斷時間複雜度:主定理公式(英語:master theorem)

常用的遞迴演算法的時間複雜度:

二分查詢:        O(log n)
二叉樹遍歷:       O(n)
最優排序矩陣:     O(n)
快排/歸併排序:    O(n log n)