數據結構與演算法概念

来源:https://www.cnblogs.com/yangyuanhu/archive/2020/02/06/12267404.html
-Advertisement-
Play Games

數據結構小白入門 數據結構指一組相互之間存在一種或多種特定關係的數據元素的集合, 當我們需要在電腦中存儲這些數據時,還涉及到數據的,組織方式,在電腦中的存儲方式,以及定義在該數據上的一組操作; 一組數據相互之間有某種關係 組織方式 存儲方式 以及可對其進行的一組操作 理解: 我們學習的最終目的是 ...


數據結構小白入門

數據結構指一組相互之間存在一種或多種特定關係的數據元素的集合,
當我們需要在電腦中存儲這些數據時,還涉及到數據的,組織方式,在電腦中的存儲方式,以及定義在該數據上的一組操作;

  • 一組數據相互之間有某種關係
  • 組織方式
  • 存儲方式
  • 以及可對其進行的一組操作
理解:

我們學習的最終目的是要在電腦中存儲一組數據,但是不得不先考慮數據的組織方式,在電腦中的存儲方式,以及可以對這些數據進行的一組操作,當然了既然是一組數據必然表明瞭這寫數據之間是存在想換的關聯關係的;關係可能還會有多種;

例如:

一組數據:12345

組織方式:從小到大

存儲方式:可使用線性存儲結構

操作:要取出最大的一個

數據結構研究方向

問題:

  • 機外處理
  • 處理要求

建模:

  • 邏輯結構
  • 基本運算

實現:

  • 存儲結構
  • 演算法

基本術語

數據(Data):

​ 所有能被電腦處理的符號的集合

數據元素(DataElement):

​ 是數據集合中的一個 個體,即數據的基本單位

數據項(DataItem):

​ 數據元素常常可分為若幹個數據項,數據項是數據具有意義的最小單位

組織數據的三個層次:

數據(表)->數據元素(行)->數據項(欄位)

實際問題中的數據成為原始數據

邏輯結構(LogicalStructure)

​ 數據元素之間的結構關係,如從小到大/一對一/一對多

物理結構(PhysicalStructure)

​ 也會叫做存儲結構,指數據在電腦內的表示,邏輯結構在電腦中的具體實現

邏輯結構

常見的邏輯結構如下:

集合:

數據元素屬於同一個集合,表示為R{}; 數據之間不存在特定關係

組織結構鬆散,任意兩節點之間都沒有鄰接關係

線性:

除了起始節點d1和終端階段dn外,每個節點都有一個前驅和一個後繼,表示為R={d1,d2...dn},數據之間存在前後順序關係

各節點按邏輯關係排列,形成一條'鏈'

樹狀:

每個元素最多有一個前驅,可以有多個後繼,表示為(D,{R}),就像一個樹幹長了多個樹枝

具備分支,層次特性,上層節點可以和下層多個節點相鄰接,但是下層節點只能和一個上層節點鄰接

圖狀:

任何兩個元素之間都可以相鄰接,表示為(D,{R})

註意:

邏輯結構

  • 與元素本身的形式,內容,無關

  • 元素的相對位置,無關

  • 與包含的節點個數,無關

存儲結構

存儲結構由 存儲節點(每個存儲節點存放一個數據元素)節點之間的邏輯關係共同組成

反過來說,一個完整的存儲結構必須可以存儲數據元素,以及元素之間的邏輯關係

存儲結構分類 (缺圖)

  • 順序存儲

    使用索引(相對起始位置)來表示數據的邏輯結構,數據被存儲在一組連續的存儲單元中

    特點:

    • 需預先分配長度,
    • 插入和刪除慢,需要移動其他元素
    • 存取數據快捷,屬於隨機存儲結構(可通過索引直接訪問任意位置數據)
  • 鏈式存儲

    藉助元素地址指針表示數據的邏輯結構,每個元素都會包含指向下一個元素的指針

    這種結構需要在節點上附加一個指針項,指出後繼節點的位置,即每個節點存儲單元包含兩個部分:[數據項,指針項]

    特點:

    • 動態分配內容,不需要預先分配記憶體
    • 插入刪除快捷,不需要移動其他元素
    • 非隨機存取結構(獲取數據必須遍歷前面的所有節點)
  • 索引存儲(Map是否屬於索引結構 很疑惑?)

    藉助索引表來指示數據元素的存儲位置

    索引表中包含了所有數據元素的地址,查詢索引表能夠快速的定位到需要的數據

    特點:

    • 索引是一份獨立於實際存放數據,的數據結構(就像書的目錄都在正文前面)
    • 索引需要占用額外的存儲空間
    • 當實際數據發生改變時需要重建索引
    • 查詢數據快
    • 插入修改,刪除慢
  • 散列存儲(哈希表)

    通過散列函數計算得出元素的位置

    特點:

    • 在散列函數不變時,相同數據會得出相同的位置
    • 存入順序和取出順序通常不一致
    • 無法完成隨機存取(指定獲取某個元素)

順序和鏈式是最基本的也是最常用的存儲結構,需要重點掌握,包括各自的優缺點,使用場景等

鏈式存儲結構可實現樹結構(邏輯結構)

運算

運算指的是某種邏輯結構上可以進行的操作;

運算分為兩類:

  • 加工型運算

    會改變原邏輯結構的內容,順序,個數等的操作

  • 引用型運行

    與加工型運算相反

常見運算:

建立,查找,讀取,插入,刪除

加工型:建立,插入,刪除

引用型:讀取,查找

演算法

演算法字面意思,計算方法;

演算法規定了求解給定類型問題所需的所有處理步驟以及執行順序,使得問題能在有限時間內機械的求解,一個演算法就是對特定問題求解步驟的一種描述,再具體一點,演算法是一段有窮的指令序列;演算法必須能使用某種語言描述;

例如:

計算1到5的和 ,這個需求,如何來實現,第一步做什麼,第二步做什麼,整個計算步驟和執行順序統稱為演算法,如果最終能夠在有限的步驟下求出正確的和,那這就是一個合格的演算法;

演算法的特點:

  • 有窮性

    演算法必須在執行有窮步後結束

  • 確定性

    演算法的每一個步驟都必須是明確定義的,

  • 可行性

    演算法中的每一步都是可以通過已實現的操作來完成的

  • 輸入

    一個演算法具備0或多個輸入

  • 輸出

    一個演算法有一個或多個輸出,它們與輸入有著特定的關係

演算法與程式的區別,演算法只是一種描述,可以使用任何語言,但是通常不能直接被電腦運行,而程式則是演算法的具體實現,使用某種電腦語言;

演算法設計應滿足的要求

  • 正確性:對於合法的輸入產生符合要求的輸出

  • 易讀性:演算法應該儘可能易讀,便於交流,這也是保證正確性的前提(註釋可提高易讀性)

  • 健壯性:當輸入非法數據時,演算法可作出適當反應而不至於崩潰(例如輸出錯誤原因);

  • 時空性:指的是演算法的時間複雜度和空間複雜度,演算法分析主要也是分析演算法的時間複雜度和空間複雜的,其目的是提高演算法的效率;

演算法分析

解決同一問題的演算法可能有多種,我們希望從中選出最優的演算法,效率高的,占用空間小的,為此我們就需要對演算法進行評估和分析;

通常評估演算法根據兩個度量

  • 時間複雜度:演算法運行完成所需的總步數(標準操作),通常是問題規模的函數

  • 空間複雜度:演算法執行時所占用的存儲空間,通常是問題規模的函數

確定演算法的計算量

  • 合理選擇一種或幾種操作作為'標準操作',無特殊說明預設以賦值操作作為標準操作;
  • 確定演算法共執行多少次標準操作,並將此次數規定為演算法的計算量
  • 以演算法在所有時輸入下的計算量最大值作為演算法的最壞情況時間複雜度
  • 以演算法在所有時輸入下的計算量最小值作為演算法的最好情況時間複雜度
  • 以演算法在所有時輸入下的計算量平均值作為演算法的平均情況時間複雜度
  • 最壞/平均情況時間複雜度都可作為時間複雜度,通常以最壞情況衡量;

註意:時間複雜度通常以量級來衡量,也就是說不需要精確的計算到底執行了幾步,而是得出其計算量的數量級即可,並忽略常數,因為當數量級足夠大時,常數對於計算量的影響可以忽略不計;

如: (n-1)(n-2) 數量級為 n^2

時間複雜度使用大O表示,如O(1)

案例:

1.
void aFunction(){
    int c = 10 + 20;
    int d = c * c;
        printf(d);
}

上列演算法若以賦值運算作為標準操作,則該演算法的計算量為2,其時間複雜度記為O(1),為什麼是O(1)呢,是因為2是一個常數,常數對於函數的增長影響並不大,所以計算量為常數時表示為O(1),按照這種方式,即使計算量為2000,同樣記為O(1),稱為常數

2.
void bFunction(int n){
  for(int i = 0;i < n;i++){ // n
    int c = 2 * i;// 1
    int d = 3 * i;// 2
  }
}

此時函數的迴圈次數由未知數n來決定,迴圈體內計算量為2,當n是一個自然數時,函數的計算量等於(n)(2),此時時間複雜度為O(n),無論用常數2對n進行加減乘除對於n的指數都沒有影響,當n足夠大時,內部的2次計算量可以忽略,所以記為O(n),稱為線性階

更粗陋的度量方法是函數體包含一層迴圈時記為O(n)

3.
void bFunction(int n){
  for(int i = 0;i < n;i++){
      for(int j = 0;j < i;j++){
      }
  }
}

外層迴圈次數為n,內層迴圈次數隨著n的增長而增長且最大值為n-1次,那麼整個函數的計算量為(n)(n-1),常數可以忽略,所以時間複雜度記為O(n^2) ,稱為平方階

粗陋的方法是有兩層嵌套迴圈,且迴圈次數都隨著n的增長而增長,所以是O(n^2),以此類推,但是要註意下麵這種情況

4.
void bFunction(int n){
  for(int i = 0;i < n;i++){
      for(int j = 0;j < 3;j++){
      }
  }
}

此時內層迴圈的迴圈次數是固定(常數)所以不會影響計算量的數量級,時間複雜度記為O(n)

5.
void bFunction(int n){
  for(int i = 3;i < n;){
      i *= 3;
  }
}

此時函迴圈次數會隨著3迴圈體中的常數3的的變化而變化,我們可以用對數來表示,

假設迴圈次數為s,迴圈條件可表示為 s = 3^s < n;(即i本身為3,其次冪會不斷的增長,但結果要小於n)

當然這裡有個條件是i的初值必須和每次乘等的值相同,形成次冪的增長;

用對數表示為s = log3n,時間複雜度記為O(log3n),常數可以忽略,所以最後是O(logn)稱之為對數階

對數階的數量級小於線性階,因為若n的值相同,對數階計算量必然小於線性階

6.
void bFunction(int n){
 for(int i = 0;i < n;i++){
     for(int j = 0;j < n;j++){
         for(int k = 0;k < n;k++){
       }
     }   
 }
}

上述演算法時間複雜度為O(n^3),3為常數,對應著迴圈的嵌套層數;也可以用O(n^C)表示,稱為多項式階

7.
void bFunction(int n){
  int num = 2;
  for(int i = 0;i < n;){ //O(n)
        num *= 2;
  }
  for (int j = 0;j<num;j++){ //O(n)
  }
}

上述函數輸入的參數n將作為迴圈次數的指數,假設迴圈次數為s, s = 2^n,那麼時間複雜度為O(2^n),

稱之為指數階,可記為O(C^n)

8.
void bFunction(int n)
{
    for(int i=0;i<n;i++){
          for(int j=0;j<n;j++){
          }
    }   
  
      for(int i=0;i<n;i++){
      }             
}

對於順序運行的演算法,總時間複雜度等於演算法中最大時間複雜度,即O(n^2)

9.
void bFunction(int n)
{
  if(n % 2 ==0){
    for(int i=0;i<n;i++){
          for(int j=0;j<n;j++){
          }
    }   
  }else{
      for(int i=0;i<n;i++){
      }             
  } 
}

對於具備分支結構的演算法,總時間複雜度等於演算法中時間複雜度最大路徑的複雜度,即O(n^2)

時間複雜度大小順序

常數 < 對數階 < 線性階 < 平方階 < 多項式階 < 指數階

O(1) < O(logn) < O(n) < O(n^2) < O(n^C) < O(C^n)

優劣:

通常具有常數階複雜度的演算法是好的演算法
具有指數階複雜度的演算法是差的演算法

個人觀點,若有錯誤敬請指出,謝謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • getElementById() 根據id獲取dom元素 沒有找到則返會Null <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id ...
  • jquery.ui實現新聞模塊 jquery也有ui,瞭解即可,用的不多,類似element ui 和bootstrap JQuery UI API: jquery.ui實現新聞模塊 draggale拖動,並用屬性handle,指定下拖動手柄 $(".drag-wrapper").draggable ...
  • jquery.color.js的使用 瞭解即可 <!--1. 引入jquery的js文件--> <script src="jquery-1.12.4.js"></script> <!--2. 引入插件的js文件--> <script src="jquery.color.js"></script> < ...
  • jQuery插件 使用插件的步驟 1. 引入jQuery文件 2. 引入插件(如果有用到css的話,需要引入css) 3. 使用插件 <!--1. 引入jquery的js文件--> <script src="jquery-1.12.4.js"></script> <!--2. 引入插件的js文件-- ...
  • 單步跟蹤調試 debugger; 控制台watch功能查看變數當前值 進入函數操作 隨著不斷點擊,不停進行迴圈,指定變數的值也在發生改變 添加斷點 跳入跳出函數 throw new Error() 主動拋出異常 後面的代碼不再運行 代碼會跳轉到離這句最近的try語句中 使用 try{ }catch( ...
  • nodemon是一種工具,通過在檢測到目錄中的文件更改時自動重新啟動節點應用程式來幫助開發基於node.js的應用程式。 nodemon並沒有要求任何對你的代碼或開發的方法中的額外變化。nodemon是一個替換包裝器node,用於在執行腳本時nodemon替換node命令行上。 安裝方法:npm i ...
  • 安裝C++環境MacOS安裝xcode查看是否安裝成功:$ g++ -vHell WorldC++ 程式的源文件通常使用擴展名 .cpp、.cp 或 .c。Hello WorldC++ 程式的源文件通常使用擴展名 .cpp、.cp 或 .c。編譯源文件$ g++ c.cpp由於命令行中未指定可執行程... ...
  • 一、ProxyHandler處理(代理伺服器) 1.使用代理IP,是爬蟲的常用手段 2.獲取代理伺服器的地址: www.xicidaili.com www.goubanjia.com 3.代理用來隱藏真實訪問中,代理不允許頻繁訪問某一個固定網站,所以代理一定要很多很多。 4.基本使用步驟: (1)設 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...