合理地組織數據,高效地處理數據是數據結構的主要研究的問題。
1.1數據結構的研究內容
數據結構主要研究非數據計算問題,即無法用數學方法建立數學模型的問題,例如建立一張學生信息表(線性)、人機對弈(樹)、最短路徑(圖)等等。
1.2基本概念和術語
1.2.1數據、數據元素、數據項、數據對象
數據:客觀事物的符號表示,使所有能輸入到計算機並被計算機程序處理的符號的總稱。如數,字符串、圖像。
數據元素:是數據的基本單位,在計算機中通常作爲一個整體進行考慮和處理。比如學生信息表中一名學生的信息,人機對弈時的一種狀態,圖中的一個頂點。
數據項:組成數據元素的、有獨立含義的、不可分割的最小單位。例如,學生的 學號、姓名、年齡等等都是數據項。
數據對象:性質相同的數據元素的集合,是數據的一個子集。例如學生中大於20歲的集合。
1.2.2數據結構
數據結構是相互之間存在一種或多種特地關係的數據源的集合。
數據結構包括邏輯結構和存儲結構兩個層次。
1.邏輯結構
數據的邏輯結構是從邏輯關係上描述數據。可以看做是從具體問題中抽象出來的數學模型。
邏輯結構有兩個要素:一是數據元素,二是關係。四種基本的邏輯關係:集合、線性‘、樹、圖。
2存儲結構
數據對象在計算機中的存儲表示稱爲存儲結構。
數據元素在計算機中有兩種基本的存儲結構,分別是順序存儲結構(數組)和鏈式存儲結構(鏈表)。
1.2.3數據類型和抽象數據類型
數據類型例如C語言中的整型、浮點型等等。抽象數據類型是用戶自己定義的、表示應用問題的數據類型,C++中可以用類表示。
1.3抽象數據類型的表示與實現
舉個例子:對複數進行操作。
①定義部分:
ADT Complex{
Creat(&C, x, y);
//構造複數C,實部爲x,虛部爲y
GetReal(C);
//返回實部
GetImag(C);
//返回虛部
Add(C1, C2);
//返回兩數之和
Sub(C1, C2);
//兩數之差
} ADT Complex
②表示部分
typedef struct
{
float Realpart; //實部
float Imagepart; //虛部
}Complex;
③實現部分
void Create(&Complex C, float x, float y)
{
C.Realpart=x;
C.Imagepart=y;
}
float GetRel(Complex C)
{
return C.Realpart;
}
float GetImag(Complex C)
{
return C.Imagepart;
}
Complex Add(Complex C1, Complex C2)
{
Complex sum;
sum.Realpart=C1.Realpart+C2.Realpart;
sum.Imagepart=C1.Imagepart+C2.Imagepart;
return sum;
}
Complex Sub(Complex C1, Complex C2)
{
Complex sum;
sum.Realpart=C1.Realpart-C2.Realpart;
sum.Imagepart=C1.Imagepart-C2.Imagepart;
return sum;
}
1.4算法和算法分析
數據結構與算法存在着本質聯繫。
1.4.1算法的定義及特性
算法是爲了解決某類問題而規定的一個有限長的操作序列。
算法需要滿足的特性:有窮性、確定性、可行性、輸入、輸出。
1.4.2評價算法優劣的基本標準
算法優劣可以從這幾個方面來評價:正確性、可讀性、健壯性、高效性(包括時間複雜度和空間複雜度)。
1.4.3算法的時間複雜度
1.問題規模和語句頻度
問題規模是算法求解問題的輸入量是多少,例如排序時數據的個數。
一條語句的重複執行次數稱爲語句頻度。
for(i=0;i<=n;i++) //n+1
{
for(j=1;j<=n;j++) //n*(n+1)
{
c[i][j]=0; //n*n
for(k=1;k<=n;k++) //n*n*(n+1)
{
c[i][j]+=a[i][j]*b[i][j]; //n*n*n
}
}
}
f(n)=2n*n*n+3n*n+2n+1
2.算法的時間複雜度定義
上例中,當n趨近於無窮大是f(n)/n*n*n=2;
比是一個不等於零的常數,就說明f(n)與n的三次是同一個數量級,記作T(n)=O(f(n))=O(n的三次)
T(n)即爲時間複雜度
3.算法時間複雜度舉例
定理:T(n)=f(n)中最高次項=O(n的m次)
常量階T(n)=O(1)
{
x++;s=0;
}
for(i=0;i<1000;i++)
{
x++;
s=0;
}
線性階
for(i=0;i<n;i++)
{
x++;
s=0;
}
平方階
x=0;y=0;
for(k=1;k<=n;k++)
{
x++;
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
y++;
}
}
對數階
fpr(i=01;i<=n;i=i*2)
{
x++;
s=0;
}
常見的時間複雜度按數量級遞增依次爲:常量階、對數階、線性階、線性對數階、平方階、立方階,,,K次方階、指數階
4.最好、最壞和平均時間複雜度
同字面意思
1.4.4空間算法複雜度
舉例說明
算法1
for(i=0;i<n/2;i++)
{
t=a[i];
a[i]=a[n-i-1];
a[n-i-1]=t;
}
算法2
for(i=0;i<n;i++)
{
b[i]=a[n-i-1];
}
for(i=0;i<n;i++)
{
a[i]=b[i];
}
相比以上兩個算法,第一個只用了一個輔助變量t,空間複雜度爲O(1),
第二個用了一個數組,空間複雜度爲O(n)