數(shù)據(jù)結(jié)構(gòu)小白入門

          數(shù)據(jù)結(jié)構(gòu)指一組相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合,
          當(dāng)我們需要在計算機中存儲這些數(shù)據(jù)時,還涉及到數(shù)據(jù)的,組織方式,在計算機中的存儲方式,以及定義在該數(shù)據(jù)上的一組操作;

          * 一組數(shù)據(jù)相互之間有某種關(guān)系
          * 組織方式
          * 存儲方式
          * 以及可對其進行的一組操作 理解:
          我們學(xué)習(xí)的最終目的是要在計算機中存儲一組數(shù)據(jù),但是不得不先考慮數(shù)據(jù)的組織方式,在計算機中的存儲方式,以及可以對這些數(shù)據(jù)進行的一組操作
          ,當(dāng)然了既然是一組數(shù)據(jù)必然表明了這寫數(shù)據(jù)之間是存在想換的關(guān)聯(lián)關(guān)系的;關(guān)系可能還會有多種;
          例如:
          一組數(shù)據(jù):12345

          組織方式:從小到大

          存儲方式:可使用線性存儲結(jié)構(gòu)

          操作:要取出最大的一個
          數(shù)據(jù)結(jié)構(gòu)研究方向
          問題:

          * 機外處理
          * 處理要求
          建模:

          * 邏輯結(jié)構(gòu)
          * 基本運算
          實現(xiàn):

          * 存儲結(jié)構(gòu)
          * 算法
          基本術(shù)語

          數(shù)據(jù)(Data):

          ? 所有能被計算機處理的符號的集合

          數(shù)據(jù)元素(DataElement):

          ? 是數(shù)據(jù)集合中的一個 個體,即數(shù)據(jù)的基本單位

          數(shù)據(jù)項(DataItem):

          ? 數(shù)據(jù)元素常??煞譃槿舾蓚€數(shù)據(jù)項,數(shù)據(jù)項是數(shù)據(jù)具有意義的最小單位
          組織數(shù)據(jù)的三個層次:
          數(shù)據(jù)(表)->數(shù)據(jù)元素(行)->數(shù)據(jù)項(字段)

          實際問題中的數(shù)據(jù)成為原始數(shù)據(jù)

          邏輯結(jié)構(gòu)(LogicalStructure)

          ? 數(shù)據(jù)元素之間的結(jié)構(gòu)關(guān)系,如從小到大/一對一/一對多

          物理結(jié)構(gòu)(PhysicalStructure)

          ? 也會叫做存儲結(jié)構(gòu),指數(shù)據(jù)在計算機內(nèi)的表示,邏輯結(jié)構(gòu)在計算機中的具體實現(xiàn)

          邏輯結(jié)構(gòu)

          常見的邏輯結(jié)構(gòu)如下:

          集合:

          數(shù)據(jù)元素屬于同一個集合,表示為R{}; 數(shù)據(jù)之間不存在特定關(guān)系

          組織結(jié)構(gòu)松散,任意兩節(jié)點之間都沒有鄰接關(guān)系

          線性:

          除了起始節(jié)點d1和終端階段dn外,每個節(jié)點都有一個前驅(qū)和一個后繼,表示為R={d1,d2...dn},數(shù)據(jù)之間存在前后順序關(guān)系

          各節(jié)點按邏輯關(guān)系排列,形成一條'鏈'

          樹狀:

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

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

          圖狀:

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

          注意:

          邏輯結(jié)構(gòu)

          *
          與元素本身的形式,內(nèi)容,無關(guān)

          *
          元素的相對位置,無關(guān)

          *
          與包含的節(jié)點個數(shù),無關(guān)

          存儲結(jié)構(gòu)

          存儲結(jié)構(gòu)由 存儲節(jié)點(每個存儲節(jié)點存放一個數(shù)據(jù)元素) 和 節(jié)點之間的邏輯關(guān)系共同組成

          反過來說,一個完整的存儲結(jié)構(gòu)必須可以存儲數(shù)據(jù)元素,以及元素之間的邏輯關(guān)系

          存儲結(jié)構(gòu)分類 (缺圖)

          *
          順序存儲

          使用索引(相對起始位置)來表示數(shù)據(jù)的邏輯結(jié)構(gòu),數(shù)據(jù)被存儲在一組連續(xù)的存儲單元中

          特點:

          * 需預(yù)先分配長度,
          * 插入和刪除慢,需要移動其他元素
          * 存取數(shù)據(jù)快捷,屬于隨機存儲結(jié)構(gòu)(可通過索引直接訪問任意位置數(shù)據(jù))
          *
          鏈?zhǔn)酱鎯?br>
          借助元素地址指針表示數(shù)據(jù)的邏輯結(jié)構(gòu),每個元素都會包含指向下一個元素的指針

          這種結(jié)構(gòu)需要在節(jié)點上附加一個指針項,指出后繼節(jié)點的位置,即每個節(jié)點存儲單元包含兩個部分:[數(shù)據(jù)項,指針項]

          特點:

          * 動態(tài)分配內(nèi)容,不需要預(yù)先分配內(nèi)存
          * 插入刪除快捷,不需要移動其他元素
          * 非隨機存取結(jié)構(gòu)(獲取數(shù)據(jù)必須遍歷前面的所有節(jié)點)
          *
          索引存儲(Map是否屬于索引結(jié)構(gòu) 很疑惑?)

          借助索引表來指示數(shù)據(jù)元素的存儲位置

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

          特點:

          * 索引是一份獨立于實際存放數(shù)據(jù),的數(shù)據(jù)結(jié)構(gòu)(就像書的目錄都在正文前面)
          * 索引需要占用額外的存儲空間
          * 當(dāng)實際數(shù)據(jù)發(fā)生改變時需要重建索引
          * 查詢數(shù)據(jù)快
          * 插入修改,刪除慢
          *
          散列存儲(哈希表)

          通過散列函數(shù)計算得出元素的位置

          特點:

          * 在散列函數(shù)不變時,相同數(shù)據(jù)會得出相同的位置
          * 存入順序和取出順序通常不一致
          * 無法完成隨機存取(指定獲取某個元素)
          順序和鏈?zhǔn)绞亲罨镜囊彩亲畛S玫拇鎯Y(jié)構(gòu),需要重點掌握,包括各自的優(yōu)缺點,使用場景等

          鏈?zhǔn)酱鎯Y(jié)構(gòu)可實現(xiàn)樹結(jié)構(gòu)(邏輯結(jié)構(gòu))

          運算

          運算指的是某種邏輯結(jié)構(gòu)上可以進行的操作;

          運算分為兩類:

          *
          加工型運算

          會改變原邏輯結(jié)構(gòu)的內(nèi)容,順序,個數(shù)等的操作

          *
          引用型運行

          與加工型運算相反

          常見運算:

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

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

          引用型:讀取,查找

          算法

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

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

          例如:

          計算1到5的和
          ,這個需求,如何來實現(xiàn),第一步做什么,第二步做什么,整個計算步驟和執(zhí)行順序統(tǒng)稱為算法,如果最終能夠在有限的步驟下求出正確的和,那這就是一個合格的算法;

          算法的特點:

          *
          有窮性

          算法必須在執(zhí)行有窮步后結(jié)束

          *
          確定性

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

          *
          可行性

          算法中的每一步都是可以通過已實現(xiàn)的操作來完成的

          *
          輸入

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

          *
          輸出

          一個算法有一個或多個輸出,它們與輸入有著特定的關(guān)系

          算法與程序的區(qū)別,算法只是一種描述,可以使用任何語言,但是通常不能直接被計算機運行,而程序則是算法的具體實現(xiàn),使用某種計算機語言;

          算法設(shè)計應(yīng)滿足的要求

          *
          正確性:對于合法的輸入產(chǎn)生符合要求的輸出

          *
          易讀性:算法應(yīng)該盡可能易讀,便于交流,這也是保證正確性的前提(注釋可提高易讀性)

          *
          健壯性:當(dāng)輸入非法數(shù)據(jù)時,算法可作出適當(dāng)反應(yīng)而不至于崩潰(例如輸出錯誤原因);

          *
          時空性:指的是算法的時間復(fù)雜度和空間復(fù)雜度,算法分析主要也是分析算法的時間復(fù)雜度和空間復(fù)雜的,其目的是提高算法的效率;

          算法分析

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

          通常評估算法根據(jù)兩個度量

          *
          時間復(fù)雜度:算法運行完成所需的總步數(shù)(標(biāo)準(zhǔn)操作),通常是問題規(guī)模的函數(shù)

          *
          空間復(fù)雜度:算法執(zhí)行時所占用的存儲空間,通常是問題規(guī)模的函數(shù)

          確定算法的計算量

          * 合理選擇一種或幾種操作作為'標(biāo)準(zhǔn)操作',無特殊說明默認以賦值操作作為標(biāo)準(zhǔn)操作;
          * 確定算法共執(zhí)行多少次標(biāo)準(zhǔn)操作,并將此次數(shù)規(guī)定為算法的計算量
          * 以算法在所有時輸入下的計算量最大值作為算法的最壞情況時間復(fù)雜度
          * 以算法在所有時輸入下的計算量最小值作為算法的最好情況時間復(fù)雜度
          * 以算法在所有時輸入下的計算量平均值作為算法的平均情況時間復(fù)雜度
          * 最壞/平均情況時間復(fù)雜度都可作為時間復(fù)雜度,通常以最壞情況衡量;

          注意:時間復(fù)雜度通常以量級來衡量,也就是說不需要精確的計算到底執(zhí)行了幾步,而是得出其計算量的數(shù)量級即可,并忽略常數(shù),因為當(dāng)數(shù)量級足夠大時,常數(shù)對于計算量的影響可以忽略不計;

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

          時間復(fù)雜度使用大O表示,如O(1)

          案例:

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

          上列算法若以賦值運算作為標(biāo)準(zhǔn)操作,則該算法的計算量為2,其時間復(fù)雜度記為O(1),為什么是O(1)呢,是因為2是一個常數(shù),常數(shù)對于函數(shù)的增長影響并不大,所以計算量為常數(shù)時表示為O(1),按照這種方式,即使計算量為2000,同樣記為O(1),稱為
          常數(shù)

          2.
          void bFunction(int n){ for(int i = 0;i < n;i++){ // n int c = 2 * i;// 1 int d
          = 3 * i;// 2 } }
          此時函數(shù)的循環(huán)次數(shù)由未知數(shù)n來決定,循環(huán)體內(nèi)計算量為2,當(dāng)n是一個自然數(shù)時,函數(shù)的計算量等于(n)(2),此時時間復(fù)雜度為O(n),無論用常數(shù)2
          對n進行加減乘除對于n的指數(shù)都沒有影響,當(dāng)n足夠大時,內(nèi)部的2次計算量可以忽略,所以記為O(n),稱為線性階

          更粗陋的度量方法是函數(shù)體包含一層循環(huán)時記為O(n)

          3.
          void bFunction(int n){ for(int i = 0;i < n;i++){ for(int j = 0;j < i;j++){ } }
          }
          外層循環(huán)次數(shù)為n,內(nèi)層循環(huán)次數(shù)隨著n的增長而增長且最大值為n-1次,那么整個函數(shù)的計算量為(n)(n-1),常數(shù)可以忽略,所以時間復(fù)雜度記為O(n^2)
          ,稱為平方階

          粗陋的方法是有兩層嵌套循環(huán),且循環(huán)次數(shù)都隨著n的增長而增長,所以是O(n^2),以此類推,但是要注意下面這種情況

          4.
          void bFunction(int n){ for(int i = 0;i < n;i++){ for(int j = 0;j < 3;j++){ } }
          }
          此時內(nèi)層循環(huán)的循環(huán)次數(shù)是固定(常數(shù))所以不會影響計算量的數(shù)量級,時間復(fù)雜度記為O(n)

          5.
          void bFunction(int n){ for(int i = 3;i < n;){ i *= 3; } }
          此時函循環(huán)次數(shù)會隨著3循環(huán)體中的常數(shù)3的的變化而變化,我們可以用對數(shù)來表示,

          假設(shè)循環(huán)次數(shù)為s,循環(huán)條件可表示為 s = 3^s < n;(即i本身為3,其次冪會不斷的增長,但結(jié)果要小于n)

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

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

          對數(shù)階的數(shù)量級小于線性階,因為若n的值相同,對數(shù)階計算量必然小于線性階

          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++){ } } } }
          上述算法時間復(fù)雜度為O(n^3),3為常數(shù),對應(yīng)著循環(huán)的嵌套層數(shù);也可以用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) } }
          上述函數(shù)輸入的參數(shù)n將作為循環(huán)次數(shù)的指數(shù),假設(shè)循環(huán)次數(shù)為s, s = 2^n,那么時間復(fù)雜度為O(2^n),

          稱之為指數(shù)階,可記為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++){ } }
          對于順序運行的算法,總時間復(fù)雜度等于算法中最大時間復(fù)雜度,即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++){ } } }
          對于具備分支結(jié)構(gòu)的算法,總時間復(fù)雜度等于算法中時間復(fù)雜度最大路徑的復(fù)雜度,即O(n^2)

          時間復(fù)雜度大小順序

          常數(shù) < 對數(shù)階 < 線性階 < 平方階 < 多項式階 < 指數(shù)階

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

          優(yōu)劣:

          通常具有常數(shù)階復(fù)雜度的算法是好的算法
          具有指數(shù)階復(fù)雜度的算法是差的算法

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

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                国产精品自拍第一页 | 免费人成在线观看视频播放 | 韩国a级黄色 | 国产精品肏屄视频 | 亚洲男人的天堂网 |