數據結構與算法基礎
1.1 數據結構研究對象
計算機解決問題的步驟:
1.3 基本概念和術語
1. 數據(data):能夠輸入到計算機中,並且能被計算機處理的符號的集合。
2. 數據元素(data element):數據的基本單位,它在計算機處理和程序設計中通常被作爲一個整體進行考慮和處理。
3. 數據項(data item):是數據不可分割的最小單位。一個數據元素可以由若干個數據項組成。
4. 數據對象(data object):是具有相同特徵的數據元素的集合,是數據的一個子集。
5. 數據結構(data structure):是相互之間存在的一種或多種特定關係的數據元素的集合。元素之間的關係稱爲結構,形式定義爲一個二元組。即:
Data_Structure=(D,S)
其中:D是數據元素的有限集,S是D上關係的有限集。
1. 數據的邏輯結構:指數據結構中數據元素之間的邏輯關係。數據邏輯的基本結構有四種:
(1)集合:結構中的數據元素之間除了“同屬於一個集合”以外,無其他關係。
(2)線性結構:結構中的數據元素之間存在一對一的關係。
(3)樹形結構:結構中的數據元素之間存在一對多的關係。
(4)圖狀結構(網狀結構):結構中的數據元素之間存在多對多的關係。
四類基本結構的圖示:(它們的複雜度依次遞增)
集合結構:線性結構:
樹狀結構:網狀結構:
數據的存儲結構(physical structure):是數據的邏輯結構在計算機內存中的存儲方式。又稱爲物理結構。
(1)順序存儲結構:是利用數據元素在存儲器中的相對位置來表示元素間的邏輯順序。
(2)鏈式存儲結構:是利用結點中的指針來表示數據元素之間的關係。(它通常藉助程序設計語言的指針來實現)
特點:藉助指示元素的存儲地址的指針表示數據元素之間的邏輯關係。
1.4數據類型與抽象類型
1.4.1 數據類型
數據類型:是在一種程序設計語言中,變量所具有的數據種類,它限定了變量的取值範圍和可做的操作。
1.4.2 抽象數據類型
抽象數據類型(abstract data type,ADT):是指一個數學模型以及定義在該模型上的一組操作。
我們不需要了解它的實現方法和細節,只關心它的邏輯特徵。
特點:使用和實現相分離,實行封裝和隱藏。在抽象數據類型設計時,把類型的定義與其實現分離開來。
抽象數據類型的三要素:元素、關係、操作。抽象數據類型可以用三元組表示爲:
(D,R,P)
其中:D是數據對象,R是D上的關係集,P是對D的基本操作集。
1.5 算法與算法分析
1.5.1 算法
算法(algorithm):是對特定問題求解步驟的一種描述,是指令的有限序列,其中每一條命令表示一個或多個操作。
算法的重要特性:
1. 有窮性:一個算法必須總是在執行有窮步驟後結束,且每一步都必須在有窮的時間內完成。
2. 可行性:一個算法中所描述的操作,必須可以通過已經實現的基本運算的有限次執行來完成。
3. 確定性:算法中的每一條指令必須沒有二義性,對於相同的輸入必須有相同的結果。
4. 一個算法有零個或多個輸入:這些輸入取自某個特定的對象的集合。
5. 一個算法有一個或多個輸出:他們是和輸入有着某些特定關係的量,通常是對輸入進行加工得到的結果。
前三條是算法的基本特性。
一個好的算法應滿足以下要求:
1. 正確性:通常包含以下幾個層次:
①程序中不含語法錯誤。
②程序對於機組給定的輸入數據都能得出滿足要求的結果
③程序對於精心選擇的、典型的、苛刻的且帶有刁難型的幾
組輸入都能得出滿足要求的結果。
④程序對一切合法輸入都能得出滿足要求的結果。
2. 可讀性:算法應該易於理解,晦澀難懂難以調試。
3. 健壯性:當輸入的數據非法時,應該返回一個表示錯誤或錯誤性質的值。
4. 高效性:算法應該具有時間執行時間和算法執行過程中的最大存儲空間兩方面的效率,時間複雜度和空間復 雜度是兩者不可兼得的。
1.5.2 算法分析
算法分析主要是指分析算法的效率。
1.算法的時間複雜度
(1)事後統計方法:主要是在算法的關鍵部位插入計時器,當算法執行時打開計時器,終止時關閉,得出算法執行時間的差值,從而衡量算法的效率。但是具有較大的缺陷。
(2)事前分析估算法:
①算法所採取的規模
②問題的規模
③程序設計語言
④編譯的代碼質量
⑤機器執行指令的速度
爲了避開軟硬件環境因素的影響,假定一個算法的運行時間只是問題規模的函數,那麼在問題規模一定的情況下,算法採取的策略將直接決定算法的效率。凡是關於時間複雜度的求法均只與問題的規模有關。
一個算法由控制結構和原操作組成。
將原操作重複執行的次數與問題規模n之間的關係記爲函數:f(n)。
當討論一個程序的運行時間時,我們注重的是時間的增長率。隨着問題規模的增大,它的增長率與f(n)的增長率相近,所以它們在數量級上是一致的。因此當問題規模n趨於∞時,把f(n)的數量級(階)成爲算法的漸近時間複雜度,簡稱時間複雜度,記爲T(n)。
T(n)=O(f(n))
它表示隨着問題規模n的增大,算法執行時間的增長率和f(n)的增長率相同。
時間複雜度的計算方法:
假定每條語句的執行時間爲單位時間,算法的時間複雜度是該算法中所有員操作語句的執行頻度之和。
例1-5 賦值語句
temp=1;
i=j;
j=temp;
時間複雜度T(n)=O(1)
算法執行時間是一個與問題規模n無關的常數,則算法的時間複雜度爲常數階,即:T(n)=O(1)。
例1-6 簡單循環
y=0;
for(k=1;k<=n;k++) //嵌套層數爲0
x++;
for(i=1;i<=n;i++) //嵌套層數爲1
for(j=1;j<=n;j++)
y++; //以這條語句的頻度爲基準,嵌套
時間複雜度T(n)=O(n2),當有若干個循環語句時,算法的時間複雜度是由嵌套層數最多的循環語句中最裏層語句的頻度決定的。
例1-7 選擇分支結構
if(x>n)
x++;
else
for(j=1;j<=n<j++)
x++;
時間複雜度T(n)=O(n)
如果是選擇分支結構,時間複雜度決定於各分支中最耗時的部分。
例1-8 在數組A[n]中查找值爲k的元素,若找到,則返回其位置i(0<=i<n),否則返回-1。
i=n-1;
while((i>=0)&&(A[i]!=k))
i--;
return i;
該問題不僅與規模n有關,而且與值爲k的元素在數組A中位置有關。所以要分情況:最好情況下(一開始就找到了)時間複雜度爲T(n)=O(1);最壞情況下(最後一次才找到目標元素)時間複雜度爲T(n)=O(n)。(複雜程度依次遞增)
2. 空間複雜度
定義:該算法所耗費的存儲空間,它也是問題規模的函數,記作S(n)=O(f(n))。漸進空間複雜度也就是空間複雜度。
一個算法在計算機上所佔用的存儲空間取決於三點:
(1) 存儲算法本身所佔用的存儲空間
(2) 算法的輸入/輸出數據所佔用的存儲空間
(3) 算法在運行過程中臨時佔用的存儲空間
總結
弄清數據結構的基本術語,弄清二元組中變量含義,區別數據的邏輯結構以及存儲結構的概念,弄清抽象數據類型(ADT)和三元組中變量含義,弄清算法的定義、特性以及算法的設計要求,重點掌握算法的時間複雜度分析方法。