数据结构和算法教程
目錄
1.1數(shù)據(jù)結構的研究內容
1.2基本概念和術語
1.2.1數(shù)據(jù),數(shù)據(jù)元素,數(shù)據(jù)項,數(shù)據(jù)對象
1.2.2數(shù)據(jù)結構(Data Structure)
1.2.3數(shù)據(jù)類型和抽象數(shù)據(jù)類型
1.3抽象數(shù)據(jù)類型的表示與實現(xiàn)
1.4算法和算法分析
算法時間復雜度的漸進表示法
漸進空間復雜度
1.1數(shù)據(jù)結構的研究內容
????????通常,用計算機解決一個問題的步驟:具體問題抽象為數(shù)學模型(實質):分析問題;提取操作對象,找出操作對象之間的關系;用數(shù)學語言描述-》稱為數(shù)據(jù)結構。設計算法。編程,調試,運行。
????????早期,計算機主要用于數(shù)值計算。隨著計算機應用領域的擴展,計算機被越來越多地用于非數(shù)值計算。
例如1 學生學籍管理系統(tǒng)
?操作對象:每位學生的信息(學號,姓名,性別,籍貫,專業(yè)....)
操作算法:查詢,插入,修改,刪除等。
操作對象之間的關系:線性關系? ? ? ? 數(shù)據(jù)結構:線性數(shù)據(jù)結構,線性表。
類似的還有圖書管理系統(tǒng),人事管理系統(tǒng),倉庫管理系統(tǒng),通訊錄
操作對象:若干行數(shù)據(jù)記錄
操作算法:查詢,插入,修改,刪除等
操作對象之間的關系:線性表
數(shù)據(jù)結構:線性數(shù)據(jù)結構
?例如2? ? ? ? 人際對弈問題
人輸入棋子:計算機進行運算推算出機器人下一步的棋局。之所以能對弈:策略已經輸入計算機,可以根據(jù)當前棋局來預測棋局的發(fā)展趨勢,甚至最后結果
計算機的操作對象:各種棋局狀態(tài),即描述棋盤的格局信息
計算機的算法:走棋,即選擇一種策略使棋局狀態(tài)發(fā)生變化(由一個格局派生出另一個格局)
- ?文件系統(tǒng)的系統(tǒng)結構圖
磁盤根目錄下有很多子目錄及文件,每個子目錄里又可以包含子目錄及文件,但每個子目錄只有一個父目錄,依次類推
?綜上所述
- 這些問題的共性都是無法用數(shù)學的公式或方程來描述,是一些“非數(shù)值計算”的程序設計問題
- 描述非數(shù)值計算問題的數(shù)學類型不是數(shù)學方程,而是諸如表,樹和圖之類的具有邏輯關系的數(shù)據(jù)
- 數(shù)據(jù)結構是一門研究非數(shù)值計算的程序設計中計算機的操作對象以及,他們之間的關系和操作的學科
1.2基本概念和術語
1.2.1數(shù)據(jù),數(shù)據(jù)元素,數(shù)據(jù)項,數(shù)據(jù)對象
數(shù)據(jù)(data)? ? ? ? 數(shù)據(jù)元素(data element)? ? ?
數(shù)據(jù)項(data item)? ? ? ? 數(shù)據(jù)對象(data object)
?1.數(shù)據(jù)(Data)
- ? ? ? ? 是能夠輸入計算機且能被計算機處理的各種符號的集合
- 信息的載體
- 是對客觀事物符號化的表示
- 能夠被計算機識別,存儲加工
- 包括:
- 數(shù)值型的數(shù)據(jù):整數(shù),實數(shù)等;
- 非數(shù)值型的數(shù)據(jù):文字,圖像,圖形,聲音等
2.數(shù)據(jù)元素(Data Element)
- 數(shù)據(jù)元素
- 是數(shù)據(jù)的基本單位,在計算機程序中通常作為一個整體進行考慮和處理
- 也簡稱為元素,或稱為記錄,結點或頂點。
- 一個數(shù)據(jù)元素可由若干個數(shù)據(jù)項組成(Data Item)
3.數(shù)據(jù)項
- 數(shù)據(jù)項
- 構成數(shù)據(jù)元素的不可分割的最小單位
- 數(shù)據(jù),數(shù)據(jù)元素,數(shù)據(jù)項三者之間的關系:
- 數(shù)據(jù)>數(shù)據(jù)元素>數(shù)據(jù)項
- 例如:學生表>個人記錄>學號,姓名.....
- 數(shù)據(jù)>數(shù)據(jù)元素>數(shù)據(jù)項
4.數(shù)據(jù)對象
- 數(shù)據(jù)對象
- 是性質相同是數(shù)據(jù)元素的集合,十數(shù)據(jù)的一個子集
- 例如:
- 整數(shù)數(shù)據(jù)對象是集合N={0,1,2,3.....};
- 字母字符數(shù)據(jù)對象是集合C={‘A’,'B',.....'Z'}
- 學籍表也可以看做一個數(shù)據(jù)對象
- 數(shù)據(jù)元素-----組成數(shù)據(jù)的基本單位
- 與數(shù)據(jù)的關系:是集合的個體
- 數(shù)據(jù)對象----性質相同的數(shù)據(jù)元素的集合
- 與數(shù)據(jù)的關系是:集合的子集
1.2.2數(shù)據(jù)結構(Data Structure)
- 數(shù)據(jù)結構
- 數(shù)據(jù)元素不是孤立存在的,他們之間存在著某種關系,數(shù)據(jù)元素相互之間的關系稱為結構(Structure)
- 是指相互之間存在一種或多種特定關系的數(shù)據(jù)元素的集合
- 或者說,數(shù)據(jù)結構是帶結構的數(shù)據(jù)元素的集合
- 數(shù)據(jù)結構包括以下三個方面的內容
- 邏輯結構
- 描述數(shù)據(jù)元素之間的邏輯關系
- 與數(shù)據(jù)的存儲無關,獨立于計算機
- 是從具體問題抽象出來的數(shù)學模型
- 物理結構(存儲結構)
- 數(shù)據(jù)元素及其關系在計算機存儲器中的結構(存儲方式)
- 是數(shù)據(jù)結構在計算機中的表示
- 邏輯結構與存儲結構的關系:
- 存儲結構是邏輯結構的映像與元素本身的映象
- 邏輯結構是數(shù)據(jù)結構的抽象,存儲結構是數(shù)據(jù)結構的實現(xiàn)
- 兩者綜合起來建立了數(shù)據(jù)元素之間的結構關系
- 邏輯結構的種類
- 劃分方法一
- (1)線性結構:有且僅有一個開始和終端結點,并且所有結點都最多只有一個直接前趨和一個直接后繼
- 例如:線性表,棧,隊列,串
- (2)非線性結構:一個結點可能有多個直接前趨和直接后繼
- 例如:樹,圖
- 劃分方法二——四類基本邏輯結構
- (1)集合結構:結構中數(shù)據(jù)元素之間除了同屬于一個集合的關系外,無任何其他關系
- (2)線性結構:結構中數(shù)據(jù)元素之間存在著一對一的線性關系
- (3)樹形結構:結構中數(shù)據(jù)元素之間存在著一對多的層次關系
- (4)圖狀結構或網狀結構:結構中的數(shù)據(jù)元素之間存在著多對多的任意關系
- 四種基本的存儲結構
- 順序存儲結構
- 用一組連續(xù)的存儲單元依次存儲數(shù)據(jù)元素,數(shù)據(jù)元素之間的邏輯關系由元素的存儲位置來表示
- C語言中用數(shù)組實現(xiàn)順序存儲結構
- 鏈式存儲結構
- 用一組任意的存儲單元存儲數(shù)據(jù)元素,數(shù)據(jù)元素之間的邏輯關系用指針來表示
- C語言中用指針(地址)來實現(xiàn)鏈式存儲結構
- 索引存儲結構
- 在存儲結點信息的同時,還建立附加的索引表
- 索引表中的每一項稱為一個索引項
- 索引項的一般形式是(關鍵字,地址)
- 關鍵字是能唯一標識一個結點的那些數(shù)據(jù)項
- 若每個結點在索引表中都有一個索引項,則該索引表稱之為稠密索引(Dense Index)若一組結點在索引表中只對應一個索引項,則該索引表稱為稀疏索引(Sparse Index)
- 散列存儲結構
- 根據(jù)結點的關鍵字直接計算出該結點的存儲地址
- 順序存儲結構
1.2.3數(shù)據(jù)類型和抽象數(shù)據(jù)類型
- 在使用高級程序設計語言編寫程序時,必須對程序中出現(xiàn)的每個變量,常量或表達式,明確說明它們所屬的數(shù)據(jù)類型
- 例如:C語言中:
- 提供int,char,float,double等基本數(shù)據(jù)類型
- 數(shù)組,結構,共用體,枚舉等構造數(shù)據(jù)類型
- 還有指針,空(void)類型
- 用戶也可以用typedef 自己定義數(shù)據(jù)類型
- 例如:C語言中:
- 一些最基本數(shù)據(jù)結構可以用數(shù)據(jù)類型來實現(xiàn),如:數(shù)組,字符串等;
- 而另一些常用的數(shù)據(jù)結構,如:棧,隊列,樹,圖等,不能直接用數(shù)據(jù)結構類型來表示
- 高級語言中的數(shù)據(jù)類型明顯地或隱含地規(guī)定了在程序執(zhí)行器件變量表達的所有可能的取值范圍,以及在這些數(shù)值范圍上所允許進行的操作
- 例如:C語言中定義變量i為int 類型,就是表示i是[-min,max]范圍的整數(shù),在這個整數(shù)集上可以進行+,-。,/,%等操作
- 數(shù)據(jù)類型的作用:1.約束變量或常量的取值范圍2.約束變量或常量的操作
- 例如:C語言中定義變量i為int 類型,就是表示i是[-min,max]范圍的整數(shù),在這個整數(shù)集上可以進行+,-。,/,%等操作
- 數(shù)據(jù)類型(Data Type)
- 定義:數(shù)據(jù)類型是一組性質相同的值的集合以及定義于這個值集合上的一組操作的總稱
- 數(shù)據(jù)類型=值的集合+值集合上的一組操作
- 抽象數(shù)據(jù)類型(Abstract Data Tpye,ADT)
- 是指一個數(shù)學模型以及定義在此數(shù)學模型上的一組操作
- 由用戶定義,從問題抽象出數(shù)據(jù)模型(邏輯結構)
- 還包括定義在數(shù)據(jù)模型上的一組抽象運算(相關操作)
- 不考慮計算機內的具體存儲結構與運算的具體實現(xiàn)算法
- 抽象數(shù)據(jù)類型的形式定義
- 抽象數(shù)據(jù)類型可用(D S P)三元組表示
- 其中:D是數(shù)據(jù)對象? ?S是D上關系集? ? ?P是對D的基本操作集
- 一個抽象數(shù)據(jù)類型的定義格式如下:
ADT? 抽象數(shù)據(jù)類型名{
? ? ? ? 數(shù)據(jù)對象:<數(shù)據(jù)對象的定義>
? ? ? ? 數(shù)據(jù)關系:<數(shù)據(jù)關系的定義>
? ? ? ? 基本操作:<基本操作的定義>
}ADT 抽象數(shù)據(jù)類型名
其中:
- 數(shù)據(jù)對象,數(shù)據(jù)關系的定義用偽代碼描述
- 基本操作的定義格式為:
- 基本操作名(參數(shù)表)
- 初始條件:(初始條件描述)
- 操作結果:(操作結果描述)
- 基本操作定義格式說明:
- 參數(shù)表:
- 賦值參數(shù) 只為操作提供輸入值
- 引用參數(shù) 以&打頭,除可提供輸入值,還將返回操作結果
- 初始條件:描述操作執(zhí)行之前數(shù)據(jù)結構和參數(shù)應滿足的條件,若不滿足則操作失敗,并返回相應出錯信息。若初始條件為空,則省略之
- 操作結果:說明操作正常完成之后,數(shù)據(jù)結構的變化狀況和應返回的結果
- 參數(shù)表:
?
1.3抽象數(shù)據(jù)類型的表示與實現(xiàn)
- 抽象數(shù)據(jù)類型可用通過固有的數(shù)據(jù)類型(如整型,實型,字符型)來表示和實現(xiàn)
- 即利用處理器中已經存在的數(shù)據(jù)類型來說明新的結構,用已經實現(xiàn)的操作作為新的操作
1.4算法和算法分析
- 算法的定義
- 對特定問題求解和步驟的一種描述,他是指令的有限序列,其中每個指令表示一個或者多個操作:簡而言之,算法就是解決問題的方法和步驟
- 算法的描述
- 自然語言:英語,中文
- 流程圖:傳統(tǒng)流程圖,NS流程圖
- 偽代碼:類語言:類c語言
- 程序代碼:C語言程序,JAVA語言程序
- 算法與程序
- 算法是解決問題的一種或者一個過程,考慮如何將輸入轉換成輸出,一個問題可以有多種算法
- 程序是用某種程序設計語言對算法的具體實現(xiàn)
- 程序=數(shù)據(jù)結構+算法
- 數(shù)據(jù)結構通過算法實現(xiàn)操作
- 算法根據(jù)數(shù)據(jù)結構設計程序
- 算法特性:一個算法必須具備以下五個重要特性
- 有窮性:一個算法必須總是在執(zhí)行有窮步之后結束,且每一步都在有窮時間內完成
- 確定性:算法中的每一條指令必須有確切的含義,沒有二義性,在任何條件下,只有唯一的一條執(zhí)行路徑,即對于相同的輸入只能得到相同的輸出
- 可行性:算法是可執(zhí)行的,算法描述的操作可以通過已經實現(xiàn)的基本操作執(zhí)行有限次來實現(xiàn)
- 輸入:一個算法有零個或者多個輸入
- 輸出:一個算法有一個或者多個輸入
- 算法設計的要求
- 正確性(Correctness):算法滿足問題要求,能正確解決問題算法轉化為程序后要注意:
- 可讀性(Readability):
- 健壯性(Robustness)
- 高效性(Efficiency)
?算法效率以下兩個方面來考慮:
- 算法時間效率的度量
- 算法時間效率可以用依據(jù)該算法編制的程序在計算機上執(zhí)行所消耗的時間來度量
- 兩種度量方法
- 事后統(tǒng)計
- 將算法實現(xiàn),測算其時間和空間開銷
- 缺點:編寫程序實現(xiàn)算法將花費較多時間和精力:所得實驗結果依賴于計算機的軟硬件等環(huán)境因素,掩蓋算法本身的優(yōu)劣
- 事前分析
- 對算法所消耗資源的一種估算方法
- 事前分析方法:
- 一個算法的運行時間是指一個算法在計算機上運行所耗費的時間大致可以等于計算機執(zhí)行一種簡單的操作(如賦值,比較,移動等)所需的時間與算法中進行的簡單操作次數(shù)乘積
- 算法運行時間=一個簡單操作所需的時間*簡單那操作次數(shù)
- 也即算法中每條語句的執(zhí)行時間之和
- 算法運行時間=每條語句執(zhí)行次數(shù)*該語句執(zhí)行一次所需要的時間
- 算法運行時間=每條語句頻度*該語句執(zhí)行一次所需的時間
- 事后統(tǒng)計
?例如:兩個n*n矩陣相乘的算法可描述為:
for(i=1;i<=n;i++) //執(zhí)行n+1次for(j=1;j<=n;j++){//n(n+1)次c[i][j]=0;//n*n次for(k=0;k<n;k++)//n*n*(n+1)次c[i][j]=c[i][j]+a[i][k]*b[k][j];//n*n*n次 }?我們把算法所耗費的時間定義為該算法中每條語句的頻度之和,則上述算法的時間消耗T(n)
為:T(n)=2n^3+3n^2+2n+1;這是一個關于n的函數(shù)
算法時間復雜度的漸進表示法
- 為了便于比較不同算法的時間效率,我們僅比較它們的數(shù)量級?
- 例如:兩個不同的算法,時間消耗分別是
- T1(n)=10n^2? ? ? ? T2(n)=5n^3
- 數(shù)量級越大越不好
- 例如:兩個不同的算法,時間消耗分別是
- 若有某個輔助函數(shù)f(n),使得當n趨近于無窮大時,T(n)/f(n)的極限值為不等于零的常數(shù),則稱f(n)是T(n)的同數(shù)量級函數(shù).記作T(n)=O(f(n)).稱O(f(n))為算法的漸進時間復雜度(O是數(shù)量級的符號),簡稱時間復雜度
對于求解矩陣相乘問題,算法耗費時間:
? ? ? ? T(n)=2n^3+3n^2+2n+1
?∞時候,T(n)/n^32,這表示n充分大時,T(n)與n^3是同階或者同數(shù)量級,引入大"O"記號,則T(n)可記為:T(n)=O(n^3)
一般情況下,不必計算所有操作的執(zhí)行次數(shù),而只考慮算法中基本操作執(zhí)行的次數(shù),它是問題規(guī)模n的某個函數(shù),用T(n)表示。
????????算法中基本語句重復執(zhí)行的次數(shù)是問題規(guī)模n的某個函數(shù)f(n) 算法的時間度量記作:
T(n)=O(f(n));
? ? ? ? 它表示隨著n的增大,算法執(zhí)行的時間的增長率和f(n)的增長率相同,稱為漸進時間復雜度。
基本語句:?
- ?算法中重復執(zhí)行次數(shù)和算法的執(zhí)行時間成正比的語句
- 對算法運行時間的貢獻最大
- 執(zhí)行次數(shù)最多
問題規(guī)模:
- n越大算法的執(zhí)行時間越長
- 排序:n為記錄數(shù)
- 矩陣:n為矩陣的階數(shù)
- 多項式:n為多項式的項數(shù)
- 集合:n為元素的集合
- 樹:n為樹的結點個數(shù)
- 圖:n為圖的頂點樹或邊數(shù)
分析算法時間復雜度的基本方法:
?
?忽略所有低次冪項和最高次冪系數(shù),體現(xiàn)出增長率的含義
1.找出語句頻度最大的那條語句作為基本語句
2.計算基本語句的頻度得到問題規(guī)模n的某個函數(shù)f(n)
3.取其數(shù)量級用符號“O”表示
時間復雜度是由嵌套最深層語句的頻度決定的
例題:
i=1;
while(i<=n)
????????i=i*2;
所以時間復雜度是O(log2? n)
?
?請注意:有的情況下,算法中基本操作重復執(zhí)行的次數(shù)還隨問題的輸入數(shù)據(jù)集不同而不同
例如:順序查找,在數(shù)組a[i]中查找值等于e的元素,返回其所在位置
for(i=0;i<n;i++)if(a[i]==e)return i+1;//找到,則返回第幾個元素return 0;- 最好情況:1次
- 最壞情況:n次
- 平均·時間復雜度為:O(n)
- 算法時間復雜度
- 最壞時間復雜度:指在最壞情況下,算法的時間復雜度
- 平均時間復雜度:值在所有可能輸入實例在等概率出現(xiàn)的情況下,算法的期望運行時間
- 最好時間復雜度:指在最好情況下,算法的時間復雜度
- 一般總是考慮在最壞情況下的時間復雜度,以保證算法的運行時間不會比他更長
?對于復雜的算法,可將它分成幾個容易估算的部分,然后利用大O的加法法則和乘法法則,計算算法的時間復雜度:
?算法時間效率的比較
- 當n取得很大時,指數(shù)時間算法和多項式時間算法在所需時間上非常懸殊
?
?時間復雜度T(n)按數(shù)量級遞增順序為:
漸進空間復雜度
- 空間復雜度:算法所需存儲空間的度量,記作:S(n)=O(f(n))其中n為問題的規(guī)模(或大小)
- 算法要占用的空間
- 算法本身要占據(jù)的空間,輸入/輸出,指令,常數(shù),變量等
- 算法要使用輔助空間
?例題:將一維數(shù)組a中的n個數(shù)逆序存放到原數(shù)組中
算法一 for(i=0;i<n/2;i++) {t=a[i];a[i]=a[n-i-1];a[n-i-1]=t; }//S(n)=O(1)稱為常數(shù):原地工作 算法二 for(i=0;i<n;i++) {b[i]=a[n-i-1]; } for(i=0;i<n;i++) {a[i]=b[i]; } //S(n)=O(n)總結
- 上一篇: python编写直角三角形边长公式_py
- 下一篇: vs2013配置qt5.7.0