1. 程式人生 > 其它 >【資料結構】緒論

【資料結構】緒論

技術標籤:資料結構資料結構演算法

資料結構-緒論

什麼是資料結構

先了解一張圖
在這裡插入圖片描述
計算中的各種資料,圖片,視訊…等等都放在記憶體中進行管理,排列成一列進行存放,在每列中又有許多小空間分別存放資料。

當資料存放在計算機記憶體時,決定了資料順序和位置結構的就是資料結構

基本概念和術語

  1. 資料(data)
    資料是對客觀事物的符號表示,在電腦科學中是指所有能輸入到計算機中並被計算機程式處理的符號的總稱。
  2. 資料元素(data element)
    資料元素是資料的基本單位,在計算機程式中通常作為一個整體進行考慮和處理。
  3. 資料物件(data object)
    資料物件是性質相同的資料元素的集合,是資料的一個子集。
  4. 資料結構(data structure)
    資料結構是相互之間存在一種或多種特定關係的資料元素的集合。
  5. 結構(structure)
    資料元素相互之間的關係稱為結構。
  6. 資料元素的四種基本結構:集合、線性結構、樹形結構、圖狀結構(網狀結構)。
  7. 集合
    結構中的資料元素之間除了“同屬於一個集合”的關係外,別無其他關係。
  8. 線性結構
    結構中的資料元素之間存在一個對一個的關係。
  9. 樹形結構
    結構中的資料元素之間存在一個對多個的關係。
  10. 圖狀結構(網狀結構)
    結構中的資料元素之間存在多個對多個的關係。

資料結構的形式定義為:資料結構是一個二元組Data_Structure = (D,S)

其中:D是資料元素的有限集,S是D上關係的有限集。

  1. 資料的邏輯結構
    結構定義中資料元素之間關係的描述就是資料元素之間的邏輯關係。即資料的邏輯結構
  2. 資料的物理結構(儲存結構)
    資料結構在計算機中的表示稱為資料的物理結構(儲存結構)。它包括資料元素的表示關係的表示

一個演算法的設計取決於選定的資料(邏輯)結構,而演算法的實現依賴於採用的儲存結構

資料元素之間的關係在計算機中有兩種不同的表示方法:順序映像非順序映像,因此也得到兩種不同的儲存結構:順序儲存結構鏈式儲存結構

  • 順序映像
    特點:藉助元素在儲存器中的相對位置來表示資料元素之間的邏輯關係
  • 非順序映像
    特點:藉助指示元素儲存地址的指標表示資料元素之間的邏輯關係。
  • 資料型別是一個值的集合和定義在這個值集上的一隻操作的總稱。

資料型別可以分為兩類:非結構的原子類、結構型別

  • 非結構的原子類
    原子型別的值不可分解,如指標型別、空型別等等。
  • 結構型別
    結構型別的值由若干成分按某種結構組成,可以分解。
  • 抽象資料型別(Abstract Data Type,簡稱ADT)
    指一個數學模型以及定義在該模型上的一組操作。抽象資料型別的定義僅取決於它的一組邏輯特性,而與其在計算機內部如何表示和實現無關,即不論其內部結構如何變化,只要它的數學特性不變,都不影響其外部的使用。

抽象資料型別的定義由一個值域和定義在該值域上的一組操作組成,按照其值的不同特性,可分為如下三種類型:原子型別、固定聚合型別、可變聚合型別

  • 原子型別
    屬原子型別的變數的值不可分割。這類抽象資料型別較少
  • 固定聚合型別
    屬於該型別的變數的值由確定數目的成分按某種結構組成。
  • 可變聚合型別
    構成可變聚合型別“值”的成分的數目不確定。

採用如下的格式定義抽象資料型別:

ADT抽象資料型別名{
	資料物件:<資料物件的定義>
	資料關係:<資料關係的定義>
	基本操作:<基本操作的定義>
}ADT抽象資料型別名

抽象資料型別的表示與實現

抽象資料型別Triplet的表示和實現:

//採用動態分配的順序儲存結構
typedef ElemType *Triplet

//----------基本操作的函式原型說明----------
//操作結果:構造了三元組T,元素e1,e2,e3分別被賦予引數v1,v2,v3的值
Status InitTriplet(Triplet &T,ElemType v1,ElemType v2,ElemType v3);
//操作結果:三元組T被銷燬
Status DestroyTriplet(Triplet &T);
//初始條件:三元組T已存在,1<=i<=3
//操作結果:用e返回T的第I元的值
Status Get(Triplet T,int i,ElemType &e);
//初始條件:三元組T已存在,1<=i<=3
//操作結果:改變T的第i元值為e
Status Put(Triplet T,int i,ElemType &e);
//初始條件:三元組T已存在
//操作結果:如果T的3個元素按升序排列,則返回1,否則返回0
Status IsAscending(Triplet T);
//初始條件:三元組T已存在
//操作結果:如果T的3個元素按降序排列,則返回1,否則返回0
Status IsDescending(Triplet T);
//初始條件:三元組T已存在
//操作結果:用e返回T的3個元素中的最大值
Status Max(Triplet T,ElemType &e);
//初始條件:三元組T已存在
//操作結果:用e返回T的3個元素中的最小值
Status Min(Triplet T,ElemType &e);

//----------基本操作的實現----------
Status InitTriplet(Triplet &T,ElemType v1,ElemType v2,ElemType v3)
{
	T = (ElemType *)malloc(3 * sizeof(ElemType));
	if(!T) exit(OVERFLOW);
	T[0] = v1;
	T[1] = v2;
	T[2] = v3;
	return OK;
}
Status DestroyTriplet(Triplet &T)
{
	free(T);
	T = NULL;
	return OK;
}
Status Get(Triplet T,int i,ElemType &e)
{
	if(i < 1 || i > 3)   return ERROR;
	e = T[i - 1];
	return OK;
}
Status Put(Triplet T,int i,ElemType &e)
{
	if(i < 1 || i > 3) return ERROR;
	T[i - 1] = e;
	return OK;
}
Status IsAscending(Triplet T)
{
	return(T[0] <= T[1])&&(T[1] <= T[2]);
}
Status IsDescending(Triplet T)
{
	return(T[0] >= T[1])&&(T[1] >= T[2]);
}
Status Max(Triplet T,ElemType &e)
{
	e = (T[0] >= T[1])?((T[0] >= T[2])?T[0]:T[2]):((T[1] >= T[2])?T[1]:T[2]);
	return OK;
}
Status Min(Triplet T,ElemType &e)
{
	e = (T[0] <= T[1])?((T[0] <= T[2])?T[0]:T[2]):((T[1] <= T[2])?T[1]:T[2]);
	return OK;
}

演算法和演算法分析

1.演算法

演算法(algorithm)是對特定問題求解步驟的一種描述,它是指令的有限序列,其中每一條指令表示一個或多個操作。

  • 演算法的特性
    • 有窮性
      • 一個演算法必須總是在執行有窮步之後結束,且每一步都可以在有窮時間內完成
    • 確定性
      • 演算法中的每一條指令必須有確切的含義,讀者理解時不會理解成另外的情況
    • 可行性
      • 演算法中描述的操作應該可以通過已經實現的基本運算執行有限次來實現
    • 輸入
      • 一個演算法有零個或多個的輸入,這些輸入取自於某個特定的物件集合
    • 輸出
      • 一個演算法有零個或多個的輸出,這些輸出和輸入有著某些特定關係的量
  1. 演算法設計的要求
    設計“好”的演算法應考慮以下的目標
  • 正確性
    • 設計或選擇的演算法應正能正確的反映需求
  • 可讀性
    • 可讀性好有助於人們對演算法的理解,晦澀難懂的程式易於隱藏較多錯誤,難以除錯和修改
  • 健壯性
    • 輸入資料非法時,演算法能夠適當的作出反應或進行處理
  • 效率與低儲存量需求
    • 效率指演算法執行的時間、儲存量需求指演算法執行過程中所需要的最大儲存空間
  1. 演算法效率的度量
    一個演算法是由控制結構(順序、分支和迴圈3種)和原操作(指固定資料型別的操作)構成的,演算法時間複雜取決於兩者的總和效果。

舉例:下面所示程式碼為兩個N*N矩陣相乘演算法,該演算法的執行時間與該基本操作重複執行的次數n^3成正比,記作T(n)=O(n ^3)。

for(i = 1; i<=n; ++i)
	for(j = 1; j<=n; ++j)
	{
		c[i][j] = 0;
		for(k = 1;k <= n; ++k)
			c[i][j] += a[i][k] * b[k][j];
	}

一般情況下,演算法中的基本操作重複執行的次數是問題規模n的某個函式f(n),演算法的時間度量記作:

T(n) = O(f(n))
它表示隨問題規模n的增大,演算法執行時間的增長率和f(n)的增長率相同,稱作演算法的漸進時間複雜度(asymptotic time complexity)

  1. 演算法的儲存空間需求
    類似於演算法的時間複雜度,空間複雜度是演算法所需儲存空間的量度,記作:
    S(n) = O(f(n))
    其中n為問題的規模。一個上機執行的程式除了需要儲存空間來寄存本身所用指令、常數、變數和輸入資料外,也需要一些對資料進行操作的工作單元和儲存一些為實現計算所需資訊的輔助空間。