資料結構中基本運算驗證性實踐路線建議——以順序表為例,資料結構路線
在資料結構的學習中,掌握基本運算是一個基礎性的工作。這種“抽象”層級的成果,適用於各種應用場合,也是訓練計算思維的根本依託之一。
在實踐性的學習路線中,實踐可以分為三個層次:驗證性、設計性和綜合性。驗證性實驗是最初步和基本的的,通過驗證課堂講的、書上寫的內容,加深對相關知識的理解;設計性實驗鍛煉的是運用某些基本知識和原理解決問題的能力;而綜合性實驗則達到綜合運用多方面的知識,解決實際問題的目標。
本文以順序表為例,結合“0207將演算法變程式”[視頻]部分建議的方法,將順序表部分的演算法變成程式。提供一個驗證性學習路線的建議,試圖設計一個支架,協助完成這一基本環節有困難的同學順利起步,也協助其他能順利學習的同學進一步理清思路。
(1)初始化線性表InitList(&L):構造一個空的線性表L(2)銷毀線性表DestroyList(&L):釋放線性表L佔用的記憶體空間(3)判線性表是否為空白表ListEmpty(L):若L為空白表,則返回真,否則返回假(4)求線性表的長度ListLength(L):返回L中元素個數(5)輸出線性表DispList(L):當線性表L不為空白時,順序顯示L中各節點的範圍(6)求線性表L中指定位置的某個資料元素GetElem(L,i,&e):用e返回L中第 i 個元素的值(7)尋找元素LocateElem(L,e):返回線性表L中第1個與e相等的序號,找不到返回0(8)插入元素ListInsert(&L, i, &e):線上性表L中的第i個位置插入元素e;(9)刪除元素ListDelete(&L, i, &e):線上性表L中刪除第i個元素,有e返回刪除的值;
驗證性實驗的設計依據“最小化”的原則進行測試。所謂最小化原則,指的是利用儘可能少的基本運算,組成一個程式,並設計main函數完成測試。
以順序表為例,給出建議的過程:
(1)目的是要測試“建立線性表”的演算法CreateList,為查看建表的結果,需要實現“輸出線性表”的演算法DispList。在研習DispList中發現,要輸出線性表,還要判斷表是否為空白,這樣,實現判斷線性表是否為空白的演算法ListEmpty成為必要。這樣,再加上main函數,這個程式由4個函數構成。main函數用於寫測試相關的代碼。
#include <....> //必要的庫檔案包括#define ... //必要的宏定義//聲明實現演算法的自訂函數,以及其他必要的自訂函數//定義用於驅動測試的main函數int mian(){ return 0;}//定義各個自訂函數
切記:(1)無從下手時,要找到參考,這是要“借力”;(2)找到參考,並未解決問題,觀摩之後,丟開參考,自行完成,這是根本的目標。用這樣的“抄之有道”,抄來的在心裡,最終的成果,來自你的心中、腦中和手中。
下面是對應的程式:
#include <stdio.h>#include <malloc.h>#define MaxSize 50 //Maxsize將用於後面定義儲存空間的大小typedef int ElemType; //ElemType在不同場合可以根據問題的需要確定,在此取簡單的inttypedef struct{ ElemType data[MaxSize]; //利用了前面MaxSize和ElemType的定義 int length;} SqList;//自訂函式宣告部分void CreateList(SqList *&L, ElemType a[], int n);//用數組建立線性表void DispList(SqList *L);//輸出線性表DispList(L)bool ListEmpty(SqList *L);//判定是否為空白表ListEmpty(L)//實現測試函數int main(){ SqList *sq; ElemType x[6]= {5,8,7,2,4,9}; CreateList(sq, x, 6); DispList(sq); return 0;}//下面實現要測試的各個自訂函數//用數組建立線性表void CreateList(SqList *&L, ElemType a[], int n){ int i; L=(SqList *)malloc(sizeof(SqList)); for (i=0; i<n; i++) L->data[i]=a[i]; L->length=n;}//輸出線性表DispList(L)void DispList(SqList *L){ int i; if (ListEmpty(L)) return; for (i=0; i<L->length; i++) printf("%d ",L->data[i]); printf("\n");}//判定是否為空白表ListEmpty(L)bool ListEmpty(SqList *L){ return(L->length==0);}
運行結果如下,符合預期:
(2)在已經建立線性表的基礎上,求線性表的長度ListLength、求線性表L中指定位置的某個資料元素GetElem、尋找元素LocateElem的演算法都可以實現了。就在原程式的基礎上增加:
增加求線性表的長度ListLength的函數並測試;
增加求線性表L中指定位置的某個資料元素GetElem的函數並測試;
增加尋找元素LocateElem的函數並測試;
如果完成尚有難度,請逐個增加並測試。下面是將這三個要求全部完成後的結果:
#include <stdio.h>#include <malloc.h>#define MaxSize 50 //Maxsize將用於後面定義儲存空間的大小typedef int ElemType; //ElemType在不同場合可以根據問題的需要確定,在此取簡單的inttypedef struct{ ElemType data[MaxSize]; //利用了前面MaxSize和ElemType的定義 int length;} SqList;//自訂函式宣告部分void CreateList(SqList *&L, ElemType a[], int n);//用數組建立線性表void DispList(SqList *L);//輸出線性表DispList(L)bool ListEmpty(SqList *L);//判定是否為空白表ListEmpty(L)int ListLength(SqList *L); //求線性表的長度ListLength(L)bool GetElem(SqList *L,int i,ElemType &e); //求某個資料元素值GetElem(L,i,e)int LocateElem(SqList *L, ElemType e); //按元素值尋找LocateElem(L,e)//實現測試函數int main(){ SqList *sq; ElemType x[6]= {5,8,7,2,4,9}; ElemType a; int loc; CreateList(sq, x, 6); DispList(sq); printf("表長度:%d\n", ListLength(sq)); //測試求長度 if(GetElem(sq, 3, a)) //測試在範圍內的情形 printf("找到了第3個元素值為:%d\n", a); else printf("第3個元素超出範圍!\n"); if(GetElem(sq, 15, a)) //測試不在範圍內的情形 printf("找到了第15個元素值為:%d\n", a); else printf("第15個元素超出範圍!\n"); if((loc=LocateElem(sq, 8))>0) //測試能找到的情形 printf("找到了,值為8的元素是第 %d 個\n", loc); else printf("值為8的元素木有找到!\n"); if((loc=LocateElem(sq, 17))>0) //測試不能找到的情形 printf("找到了,值為17的元素是第 %d 個\n", loc); else printf("值為17的元素木有找到!\n"); return 0;}//下面實現要測試的各個自訂函數//用數組建立線性表void CreateList(SqList *&L, ElemType a[], int n){ int i; L=(SqList *)malloc(sizeof(SqList)); for (i=0; i<n; i++) L->data[i]=a[i]; L->length=n;}//輸出線性表DispList(L)void DispList(SqList *L){ int i; if (ListEmpty(L)) return; for (i=0; i<L->length; i++) printf("%d ",L->data[i]); printf("\n");}//判定是否為空白表ListEmpty(L)bool ListEmpty(SqList *L){ return(L->length==0);}//求線性表的長度ListLength(L)int ListLength(SqList *L){ return(L->length);}//求某個資料元素值GetElem(L,i,e)bool GetElem(SqList *L,int i,ElemType &e){ if (i<1 || i>L->length) return false; e=L->data[i-1]; return true;}//按元素值尋找LocateElem(L,e)int LocateElem(SqList *L, ElemType e){ int i=0; while (i<L->length && L->data[i]!=e) i++; if (i>=L->length) return 0; else return i+1;}
運行結果是:
(3)其餘的4個基本運算:插入資料元素ListInsert、刪除資料元素ListDelete、初始化線性表InitList、銷毀線性表DestroyList都可以同法完成。
剛才的測試函數已經變得龐大。基本運算的模組保留,用於測試的main函數可以改變。main函數的針對性越強,實踐越有效。
例如,下面的測試函數,目標就是初始化線性表InitList和插入資料元素ListInsert兩個演算法:
//實現測試函數int main(){ SqList *sq; InitList(sq); ListInsert(sq, 1, 5); ListInsert(sq, 2, 3); ListInsert(sq, 1, 4); DispList(sq); return 0;}
得到的結果是:
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。