資料結構與演算法(1)資料組織方式、空間利用率、演算法的重要性——ZJU
阿新 • • 發佈:2021-11-06
資料結構與演算法(1)資料組織方式、空間利用率、演算法的重要性——ZJU
1.1資料結構基本概念
1.1.1解決問題方法的效率, 跟資料的組織方式有關
思考問題:如何在書架上擺放圖書?
不同的擺放方法(即資料的組織方式),影響著插入新圖書與查詢圖書的效率(即解決問題方法的效率),例如,亂放與按類歸類後按字母順序排列。
故有:解決問題方法的效率, 跟資料的組織方式有關
1.1.2解決問題方法的效率, 跟空間的利用效率有關
迴圈法與遞迴法實現例子
例2:寫程式實現一個函式PrintN,使得
傳入一個正整數為N的引數後,能順序
列印從1到N的全部正整數
迴圈法:
void PrintN ( int N ) { int i; for ( i=1; i<=N; i++ ){ printf(“%d\n”, i ); } return; }
遞迴法:
void PrintN ( int N )
{ if ( N ){//N!=0時進行遞迴呼叫,N==0時直接返回,故列印時從1開始
PrintN( N – 1 );
printf(“%d\n”, N );
}
return;
}
執行後會發現遞迴法並不能滿足要求,直接跳出(吃記憶體),迴圈法正常執行。
故有:解決問題方法的效率, 跟空間的利用效率有關
1.1.3解決問題方法的效率, 跟演算法的巧妙程度有關
冪指數多項式求和——迴圈累次相加和秦九韶演算法
寫程式計算給定多項式在給定點x
處的值
//迴圈累次相加:
double f( int n, double a[], double x ) { int i; double p = a[0]; for ( i=1; i<=n; i++ ) p += (a[i] * pow(x, i)); return p; }
//秦九韶演算法:
double f( int n, double a[], double x )
{ int i;
double p = a[n];
for ( i=n; i>0; i-- )
p = a[i-1] + x*p;
return p;
}
兩者的執行時間是不相同的,進行執行測試:
其中注意幾點:
-
使用clock()進行時鐘計時
clock():捕捉從程式開始執行到clock()被呼叫時所耗費的時間。這個 時間單位是clock tick,即“時鐘打點”。 //其中常數CLK_TCK(或CLOCKS_PER_SEC):機器時鐘每秒所走的時鐘打點數
-
當執行程式的時間太短但必須要進行計時時,可以重複執行N次(迴圈),測算時間後/N。
普通的執行一次計時程式:
#include <stdio.h>
#include <time.h>
clock_t start, stop;/* clock_t是clock()函式返回的變數型別 */
double duration;/* 記錄被測函式執行時間,以秒為單位 */
int main ()
{ /* 不在測試範圍內的準備工作寫在clock()呼叫之前*/
start = clock(); /* 開始計時 */
MyFunction(); /* 把被測函式加在這裡 */
stop = clock(); /* 停止計時 */
duration = ((double)(stop - start))/CLK_TCK;
/* 計算執行時間 */
/* 其他不在測試範圍的處理寫在後面,例如輸出duration的值 */
return 0;
}
添加了重複執行後的實現程式:
#include <stdio.h>
#include <time.h>
#include <math.h>
define MAXK 1e7 /* 被測函式最大重複呼叫次數 */
clock_t start, stop;
double duration;
#define MAXN 10 /* 多項式最大項數,即多項式階數+1 */
double f1( int n, double a[], double x );
double f2( int n, double a[], double x );
int main ()
{ int i;
double a[MAXN]; /* 儲存多項式的係數 */
for ( i=0; i<MAXN; i++ ) a[i] = (double)i;
start = clock();
for ( i=0; i<MAXK; i++ ) /* 重複呼叫函式以獲得充分多的時鐘打點數*/
f1(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start))/CLK_TCK/MAXK;
printf("ticks1 = %f\n", (double)(stop - start));
printf("duration1 = %6.2e\n", duration);
start = clock();
for ( i=0; i<MAXK; i++ ) /* 重複呼叫函式以獲得充分多的時鐘打點數*/
f2(MAXN-1, a, 1.1);
stop = clock();
duration = ((double)(stop - start))/CLK_TCK/MAXK;
printf("ticks2 = %f\n", (double)(stop - start));
printf("duration2 = %6.2e\n", duration);
return 0
}
故有:解決問題方法的效率, 跟演算法的巧妙程度有關
1.1.4抽象資料型別(Abstract Data Type )
-
資料型別
資料物件集
資料集合相關聯的操作集
(可能面向物件的程式語言更容易理解。)
-
抽象:描述資料型別的方法不依賴於具體實現
與存放資料的機器無關
與資料儲存的物理結構無關
與實現操作的演算法和程式語言均無關
只描述資料物件集和相關操作集 “是什麼 ”,並不涉及 “如何做到 ”的問題
個人的理解:
- 抽象資料型別類似於“概念”一說,並不涉及具體、個別,而是使用抽象的概括進行說明,可以認為即為大綱,不過分細分內容,不涉及如何具體實現,該抽象資料型別可以適用於個別具體的物件(物件集和操作集)。
- 資料結構的含義,大體為資料物件中資料的聯絡及對資料的操作、函式。
- 該節課講的內容為:資料組織方式、空間利用率、演算法的重要性。