第一篇:《數據結構》實驗報告——排序
《數據結構》實驗報告 排序
實驗題目:
輸入十個數,從插入排序,快速排序,選擇排序三類算法中各選一種編程實現。
實驗所使用的數據結構內容及編程思路:
1.插入排序:直接插入排序的基本操作是,將一個記錄到已排好序的有序表中,從而得到一個新的,記錄增一得有序表。
一般情況下,第i趟直接插入排序的操作為:在含有i-1個記錄的有序子序列r[1..i-1]中插入一個記錄r[i]后,變成含有i個記錄的有序子序列r[1..i];并且,和順序查找類似,為了在查找插入位置的過程中避免數組下標出界,在 r[0]處設置哨兵。在自i-1起往前搜索的過程中,可以同時后移記錄。整個排序過程為進行n-1趟插入,即:先將序列中的第一個記錄看成是一個有序的子序列,然后從第2個記錄起逐個進行插入,直至整個序列變成按關鍵字非遞減有序序列為止。
2.快速排序:基本思想是,通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。
假設待排序的序列為{L.r[s],L.r[s+1],?L.r[t]},首先任意選取一個記錄(通常可選第一個記錄L.r[s])作為樞軸(或支點)(pivot),然后按下述原則重新排列其余記錄:將所有關鍵字較它小的記錄都安置在它的位置之前,將所有關鍵字較大的記錄都安置在它的位置之后。由此可以該“樞軸”記錄最后所羅的位置i作為界線,將序列{L.r[s],?,L.r[t]}分割成兩個子序列{L.r[i+1],L.[i+2],?,L.r[t]}。這個過程稱為一趟快速排序,或一次劃分。
一趟快速排序的具體做法是:附設兩個指針low和high,他們的初值分別為low和high,設樞軸記錄的關鍵字為pivotkey,則首先從high所指位置起向前搜索找到第一個關鍵字小于pivotkey的記錄和樞軸記錄互相交換,然后從low所指位置起向后搜索,找到第一個關鍵字大于pivotkey的記錄和樞軸記錄互相 1 交換,重復這兩不直至low=high為止。
具體實現上述算法是,每交換一對記錄需進行3次記錄移動(賦值)的操作。而實際上,在排列過程中對樞軸記錄的賦值是多余的,因為只有在一趟排序結束時,即low=high的位置才是樞軸記錄的最后位置。由此可以先將樞軸記錄暫存在r[0]的位置上,排序過程中只作r[low]或r[high]的單向移動,直至一趟排序結束后再將樞軸記錄移至正確位置上。
整個快速排序的過程可遞歸進行。若待排序列中只有一個記錄,顯然已有序,否則進行一趟快速排序后再分別對分割所得的兩個子序列進行快速排序。
3.簡單選擇排序:其操作為,通過n-i次關鍵字間的比較,從n-i+1個記錄中選出關鍵字最小的記錄,并和第i(1≤i≤n)個記錄交換之。
顯然,對L.r[1?n]中的記錄進行簡單選擇排序的算法為:令i從1至n-1,進行n-1趟選擇操作。可以看出,簡單選擇排序過程中,所需進行記錄移動的操作次數較少,其最小值為“0”,最大值為3(n-1)。然后,無論記錄的初始排列如何,所需進行的關鍵字之間的比較次數相同,均為n(n-1)/2。
程序清單: 1.插入排序: #include
for(i=1;i<=num.length;i++)printf(“%d ”,num.key[i]);} 測試用例:
輸入:23 34 12 98 56 45 67 8 9 37 輸出:charu:8 9 12 23 34 37 45 56 67 98 2快速排序: #include
for(i=1;i<=num.length;i++)printf(“%d ”,num.key[i]);} 測試用例:
輸入:23 34 12 98 56 45 67 8 9 37 輸出:charu:8 9 12 23 34 37 45 56 67 98 3選擇排序: #include
intselectminkey(structsqlist *l,int a){ inti,j=a;for(i=a;i<=l->length;i++)if(l->key[i]
for(i=1;i<=num.length;i++)printf(“%d ”,num.key[i]);} 測試用例:
輸入:23 34 12 98 56 45 67 8 9 37 輸出:charu:8 9 12 23 34 37 45 56 67 98
編程感想: 本次編程總共使用了三種排序方法,而這三種編程方法放在一起進行編寫時,很容易就讓我們對齊難易程度有了更深刻的了解。
首先,三種排序中,我們都像查表那樣,設置了哨兵,而哨兵的使用可以減少對整個表的驗空操作,使程序更加節省空間。
其次,對于插入排序,每次都要對一段序列進行檢索,每排一次所要檢索的序列長度減一,其時間發雜度為O(n^2)。
接著,對于快速排序,這個程序是比較復雜的,總共是3個函數,并且使用了遞歸的方法,這是但是,這種算法卻是最優越的,平均性能也是最好的,我在編這個程序時,對其排序的思想有了進一步的了解,并努力拿他與冒泡排序進行比較,看出了些許其優越性。
還有,就是選擇排序,簡單選擇排序思路簡單,易于進行,但其時間發雜度與簡單插入排序方法一樣,都是O(n^2),性能不如快速排序。
最后,本次試驗是數據結構課的最后一次實驗,經過數據結構試驗課的鍛煉,使我對數據結構有了更深刻的理解,對我對其知識起到了重要的影響,增加了我編程的實踐活動,為我將來進一步學習打下了基礎。
第二篇:數據結構內排序實驗報告
一、實驗目的
1、了解內排序都是在內存中進行的。
2、為了提高數據的查找速度,需要對數據進行排序。
3、掌握內排序的方法。
二、實驗內容
1、設計一個程序exp10—1.cpp實現直接插入排序算法,并輸出{9,8,7,6,5,4,3,2,1,0}的排序過程。
(1)源程序如下所示:
//文件名:exp10-1.cpp #include
//線性表中最多元素個數 typedef int KeyType;typedef char InfoType[10];typedef struct
//記錄類型 {
KeyType key;
//關鍵字項
InfoType data;//其他數據項,類型為InfoType } RecType;void InsertSort(RecType R[],int n)//對R[0..n-1]按遞增有序進行直接插入排序 { int i,j,k;RecType temp;for(i=1;i { temp=R[i]; j=i-1; //從右向左在有序區R[0..i-1]中找R[i]的插入位置 while(j>=0 && temp.key { R[j+1]=R[j];//將關鍵字大于R[i].key的記錄后移 j--; } R[j+1]=temp; //在j+1處插入R[i] printf(“i=%d,”,i);//輸出每一趟的排序結果 printf(“插入%d,結果為: ”,temp); for(k=0;k printf(“%3d”,R[k].key); printf(“n”);} } void main(){ int i,k,n=10; KeyType a[]={9,8,7,6,5,4,3,2,1,0};RecType R[MAXE];for(i=0;i R[i].key=a[i];printf(“初始關鍵字: ”);//輸出初始關鍵字序列 for(k=0;k printf(“%3d”,R[k].key);printf(“n”);InsertSort(R,n);printf(“最后結果: ”);//輸出初始關鍵字序列 for(k=0;k printf(“%3d”,R[k].key);printf(“n”);}(2)運行的結果如下圖所示: 2、設計一個程序exp10—2.cpp實現希爾插入排序算法,并輸出{9,8,7,6,5,4,3,2,1,0}的排序過程。 (1)源程序如下所示: //文件名:exp10-2.cpp #include //線性表中最多元素個數 typedef int KeyType;typedef char InfoType[10];typedef struct //記錄類型 { KeyType key;//關鍵字項 InfoType data;//其他數據項,類型為InfoType } RecType;void ShellSort(RecType R[],int n)//希爾排序算法 { int i,j,d,k;RecType temp;d=n/2; //d取初值n/2 while(d>0) { for(i=d;i { j=i-d; while(j>=0 && R[j].key>R[j+d].key) { temp=R[j]; //R[j]與R[j+d]交換 R[j]=R[j+d]; R[j+d]=temp; j=j-d; } } printf(“d=%d: ”,d);//輸出每一趟的排序結果 for(k=0;k printf(“%3d”,R[k].key); printf(“n”); d=d/2; //遞減增量d } } void main(){ int i,k,n=10;KeyType a[]={9,8,7,6,5,4,3,2,1,0};RecType R[MAXE];for(i=0;i R[i].key=a[i];printf(“初始關鍵字: ”);//輸出初始關鍵字序列 for(k=0;k printf(“%3d”,R[k].key);printf(“n”);ShellSort(R,n);printf(“最后結果: ”); //輸出初始關鍵字序列 for(k=0;k printf(“%3d”,R[k].key);printf(“nn”);}(2)結果如下圖所示: 3、設計一個程序exp10—3.cpp實現冒泡排序算法,并輸出{9,8,7,6,5,4,3,2,1,0}的排序過程。 (1)源程序如下所示: //文件名:exp10-3.cpp #include //線性表中最多元素個數 typedef int KeyType;typedef char InfoType[10];typedef struct //記錄類型 { KeyType key; //關鍵字項 InfoType data; //其他數據項,類型為InfoType } RecType;void BubbleSort(RecType R[],int n)//冒泡排序算法 { int i,j,k;RecType temp;for(i=0;i { for(j=n-1;j>i;j--)//比較,找出本趟最小關鍵字的記錄 if(R[j].key { temp=R[j];//R[j]與R[j-1]進行交換,將最小關鍵字記錄前移 R[j]=R[j-1]; R[j-1]=temp; } printf(“i=%d,冒出的最小關鍵字:%d,結果為: ”,i,R[i].key);//輸出每一趟的排序結果 for(k=0;k printf(“%2d”,R[k].key); printf(“n”);} } void main(){ int i,k,n=10;KeyType a[]={9,8,7,6,5,4,3,2,1,0};RecType R[MAXE];for(i=0;i R[i].key=a[i];printf(“初始關鍵字: ”);//輸出初始關鍵字序列 for(k=0;k printf(“%2d”,R[k].key);printf(“n”);BubbleSort(R,n);printf(“最后結果: ”);//輸出初始關鍵字序列 for(k=0;k printf(“%2d”,R[k].key);printf(“n”);}(2)結果如下圖所示: 電 子 科 技 大 學 實 驗 報 告 學生姓名:XXX 學 號:20*** 指導教師:劉嶠 實驗地點:信軟機房306 實驗時間:2014/6/20 一、實驗室名稱:軟件實驗室 二、實驗項目名稱:數據結構與算法—排序與查找 三、實驗學時:4 四、實驗原理: 快速排序的基本思想是:通過一躺排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一不部分的所有數據都要小,然后再按次方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。 假設要排序的數組是A[1]……A[N],首先任意選取一個數據(通常選用第一個數據)作為關鍵數據,然后將所有比它的數都放到它前面,所有比它大的數都放到它后面,這個過程稱為一躺快速排序。一躺快速排序的算法是: 1)設置兩個變量I、J,排序開始的時候I:=1,J:=N 2)以第一個數組元素作為關鍵數據,賦值給X,即X:=A[1]; 3)從J開始向前搜索,即(J:=J-1),找到第一個小于X的值,兩者交換; 4)從I開始向后搜索,即(I:=I+1),找到第一個大于X的值,兩者交換; 5)重復第3、4步,直到I=J。 二分法查找(折半查找)的基本思想: (1)確定該區間的中點位置:mid=(low+high)/2 min代表區間中間的結點的位置,low代表區間最左結點位置,high代表區間最右結點位置 (2)將待查a值與結點mid的關鍵字(下面用R[mid].key)比較,若相等,則查找成功,否則確定新的查找區間: A)如果R[mid].key>a,則由表的有序性可知,R[mid].key右側的值都大于a,所以等于a的關鍵字如果存在,必然在R[mid].key左邊的表中,這時high=mid-1; B)如果R[mid].key C)如果R[mid].key=a,則查找成功。 (3)下一次查找針對新的查找區間,重復步驟(1)和(2) (4)在查找過程中,low逐步增加,high逐步減少,如果high 五、實驗目的: 本實驗通過實現快速排序和折半查找算法,使學生理解如何實現快速查找和排序的基本算法思想。通過練習,加強對算法的理解,提高編程能力。 六、實驗內容: (1)實現數據序列的輸入; (2)實現快速排序算法,并對輸入的序列排序后輸出; (3)實現折半查找算法,并在步驟(2)排序后的序列上,進行任意地 查找,并輸出查詢結果。 七、實驗器材(設備、元器件): 八、數據結構及程序 #include #define MAX_LEN 100 void Sort(int *data,int left,int right){ int i,j,temp; i=left; j=right; temp=data[left]; if(left>right) return; while(i!=j){ while(data[j]>=temp&&j>i) j--; if(j>i) data[i++]=data[j]; while(data[i]<=temp&&j>i) i++; if(j>i) data[j--]=data[i]; } data[i]=temp; Sort(data,left,i-1);PC機一臺,裝有C/C++語言集成開發環境。 Sort(data,i+1,right);} int Search(int *data,int start,int end,int key,int num){ int result; int p =(start + end)/ 2; if(data[p] == key&&start<=end){ result = p; num++; if(data[p] > key) result = Search(data, start, p, key,num); else result = Search(data, p + 1, end, key,num); return result; } else if(num==0&&start>end){ result =-1; printf(“n 404 NO FOUNDn”); return result; } else if(num!=0&&start>end){ result=-1; if(num==1) printf(“nFounded number only one”); else printf(“nFounded number more than one”); return result; } else if(result!=-1){ if(data[p] > key) result = Search(data, start, p-1, key, num); else result = Search(data, p + 1, end, key, num); return result; } else { result=-1; return result; } } void loadFile(int *data,char *filename,int n){ int i; FILE *pfile=NULL; pfile=fopen(filename,“r”); if(!pfile){ printf(“Open file failn”); exit(0); } else printf(“Open file success!n”); for(i = 0;i < n;i++) fscanf(pfile , “%d ”,&data[i]);} int main(int argc, const char * argv[]){ int input=1,data[MAX_LEN],num=0,key=1,i,cmd; char filename[100]; printf(“Choose Mode :n 1.Input Mode 2.File Moden”); scanf(“%d”,&cmd); if(cmd==1){ printf(“Input data :(Enter 0 to detemine)n”); while(input!=0){ printf(“Enter the %d data :”,num+1); scanf(“%d”,&input); if(input!=0){ data[num]=input; num++; } } } else{ printf(“nInput the address of the file: ”); scanf(“%s”,filename); printf(“nInput the number of elem: ”); scanf(“%d”,&num); loadFile(data,filename,--num); } Sort(data, 0, num); printf(“nSort result: ”); for(i=1;i<=num;i++) printf(“%d ”,data[i]); printf(“nn”); while(key!=0){ printf(“nInput a key to search :(Enter 0 to detemine)”); scanf(“%d”,&key); if(key!=0) Search(data, 0, num, key, 0); } return 0;} 九、程序運行結果: 1.打開程序: 2.嘗試手動輸入模式: 3.搜索已存在數: 4.搜索不存在數: 5.嘗試文件讀入模式并搜索 實驗成功。 十、實驗結論: 使用好的排序與查找算法對于程序的運行效率至關重要,一個好的算法,適合的算法能使計算機對數據的處理事半功倍,而選用錯誤的算法,不但可能事倍功半,還有可能造成不穩定因素。 快速排序的時間復雜度為n(log2n),是排序算法中最為快速的一種,但是不穩定,對基本有序的序列效率較差。 二分查找算法在查找算法中,速度快,效率高,但是要求數據要有序。 十一、總結及心得體會: 當空間充足,對穩定性要求不高的情況,排序算法宜使用快速排序。 快速排序和二分查找配合,可以以較高的效率查找目標元素。 北京郵電大學 數據結構試驗報告 實驗名稱: 實驗四 排序 學生姓名: 班 級: 班內序號: 學 號: 日 期: 2014年1月4日 實驗目的 學習、實現、對比各種排序算法,掌握各種排序算法的優劣,以及各種算法使用的情況。實驗內容 2.1 題目1 使用簡單數組實現下面各種排序算法,并進行比較。排序算法: 1、插入排序 2、希爾排序 3、冒泡排序 4、快速排序 5、簡單選擇排序 6、堆排序(選作) 7、歸并排序(選作) 8、基數排序(選作) 9、其他 要求: 1、測試數據分成三類:正序、逆序、隨機數據 2、對于這三類數據,比較上述排序算法中關鍵字的比較次數和移動次數(其中關鍵字交換計為3次移動)。 3、對于這三類數據,比較上述排序算法中不同算法的執行時間,精確到微秒(選作) 4、對2和3的結果進行分析,驗證上述各種算法的時間復雜度 編寫測試main()函數測試線性表的正確性。程序分析 3.1 存儲結構 順序存儲結構——數組 3.2 關鍵算法分析 1.插入排序:依次將待排序的序列中的每一個記錄插入到先前排序好的序列中,直到全部記錄排序完畢 void Insertsort(int r[],int n,int* compare,int* move)//插入排序 { *compare=0;*move=0;int i;int j;for(i=1;i (*compare)++; (*move)++; r[j+1]=r[j];} if(j>=0)(*compare)++;r[j+1]=x;} } 2.希爾排序:先將整個序列分割成若干個子列,分別在各個子列中運用直接插入排序,待整個序列基本有序時,再對全體記錄進行一次直接插入排序 void ShellInsert(int r[],int n,int* compare,int* move)//希爾排序 { *compare=0;*move=0;int j;10 9 12 12 20 20 31 for(int d=n/2;d>=1;d=d/2)//間距越來越小 { for(int i=d;i<=n-1;i++)//從a[d]往后逐個元素確定是否需要前移 { if(r[i] { int x=r[i]; for(j=i-d;(j>=0)&&(x { (*compare)++; (*move)++; r[j+d]=r[j]; } if(j>=0)(*compare)++; r[j+d]=x;} else(*compare)++;} } } 3.冒泡排序:兩兩比較相鄰記錄的關鍵碼,如果反序則交換,直到沒有反序記錄為止 void Bubblesort(int r[],int n,int* compare,int* move)//交換(冒泡)排序 { *compare=0;*move=0;int x;for(int j=0;j for(int i=n-1;i>j;i--) { if(r[i] { (*compare)++; (*move)+=3; x=r[i]; r[i]=r[i-1]; r[i-1]=x; } else(*compare)++; } } } 4.快速排序:首先選擇一個基準,將記錄分割為兩部分,左支小于或等于基準,右支則大于基準,然后對兩部分重復上述過程,直至整個序列排序完成 int Partion(int r[],int first,int end,int* compare,int* move)//快速排序中的軸定位 { int i=first;int j=end;int zhou=r[i];//默認第一個元素為軸 while(i { (*compare)++; j--;} if(i r[i]=r[j];//發現軸右側的某數比軸值小,將其前置 } while((i (*compare)++; (*move)++; r[j]=r[i];//發現軸左側的某數比軸值小,將其后置 } } r[i]=zhou;//最后確定軸的位置 return i;} void Qsort(int r[],int i,int j,int* compare,int* move)//快速排序 { if(i int min=i; for(int j=i+1;j { (*compare)++; if(r[j] min=j;//記錄下當前找到的最小值的位置 } if(min!=i) {(*move)+=3; int Min; Min=r[min]; r[min]=r[i]; r[i]=Min; } } } 程序運行結果 4.1主函數流程圖 4.2程序運行框圖 實驗心得 1.調試時出現的問題及解決的方法 在初期構思代碼的時候,首先構造了各種算法的基本實現代碼,封裝成類,已經能夠實現七種排序的基本功能,并且測試無誤。 之后考慮如何能簡化代碼以實現多達七種排序算法的簡單調用、亂序和順序以及逆序數據的分別排序和性能指標統計(算法移動次數和比較次數的精確統計)。2.心得體會 程序的優化是一個艱辛的過程,如果只是實現一般的功能,將變得容易很多,當加上優化,不論是效率還是結構優化,都需要精心設計。3.改進 本程序代碼設計時運用了遞歸的調用方式,效率還可以通過將其轉換為棧模擬的方式得以提高。另外還可以進一步考慮算法時間的精確統計,以便從時間角度比較這幾種排序算法的優劣。 完整源代碼 #include void Insertsort(int r[],int n,int* compare,int* move);void ShellInsert(int r[],int n,int* compare,int* move);void Bubblesort(int r[],int n,int* compare,int* move);int Partion(int r[],int first,int end,int* compare,int* move);void Qsort(int r[],int i,int j,int* compare,int* move);void Selectsort(int r[],int n,int* compare,int* move); void Insertsort(int r[],int n,int* compare,int* move)//插入排序 { *compare=0; { } } void ShellInsert(int r[],int n,int* compare,int* move)//希爾排序 { int x=r[i];for(j=i-1;x } if(j>=0)(*compare)++;r[j+1]=x;(*move)++;r[j+1]=r[j];*move=0;int i;int j;for(i=1;i (*compare)++; *compare=0; { for(int i=d;i<=n-1;i++)//從a[d]往后逐個元素確定是否需要前移 { } } } void Bubblesort(int r[],int n,int* compare,int* move)//交換(冒泡)排序 { { for(int i=n-1;i>j;i--) { if(r[i] { (*compare)++; (*move)+=3;*compare=0;*move=0;int x;if(r[i] int x=r[i]; for(j=i-d;(j>=0)&&(x }(*compare)++;(*compare)++;(*move)++;r[j+d]=r[j];*move=0;int j;for(int d=n/2;d>=1;d=d/2)//間距越來越小 if(j>=0) r[j+d]=x;} else(*compare)++;for(int j=0;j x=r[i]; r[i]=r[i-1]; r[i-1]=x; } } else(*compare)++; } } int Partion(int r[],int first,int end,int* compare,int* move)//快速排序中的軸定位 { int i=first;int j=end;int zhou=r[i];//默認第一個元素為軸 while(i { } if(i } if(i r[i]=r[j];//發現軸右側的某數比軸值小,將其前置 (*move)++; r[j]=r[i];//發現軸左側的某數比軸值小,將其后置 } } r[i]=zhou;//最后確定軸的位置 return i;} void Qsort(int r[],int i,int j,int* compare,int* move)//快速排序 { if(i void Selectsort(int r[],int n,int* compare,int* move)//選擇排序 { { int min=i; for(int j=i+1;j { (*compare)++; if(r[j] min=j;//記錄下當前找到的最小值的位置 } if(min!=i) {(*move)+=3; int Min; Min=r[min]; r[min]=r[i]; r[i]=Min; } } } void main(){ int i;int compare=0;int move=0;cout<<“請您先輸入一個正序數組哦”< cout<<“再輸入一個逆序數組~~~”< cout<<“最后輸入一個亂序數組~~~”< 注意:實驗結束后提交一份實驗報告電子文檔 電子文檔命名為“學號+姓名”,如:E01214058宋思怡 《數據結構》實驗報告 (一)學號:姓名:專業年級: 實驗名稱:線性表 實驗日期:2014年4月14日 實驗目的: 1、熟悉線性表的定義及其順序和鏈式存儲結構; 2、熟練掌握線性表在順序存儲結構上實現基本操作的方法; 3、熟練掌握在各種鏈表結構中實現線性表基本操作的方法; 4、掌握用 C/C++語言調試程序的基本方法。 實驗內容: 一、編寫程序實現順序表的各種基本運算,并在此基礎上設計一個主程序完成如下功能: (1)初始化順序表L; (2)依次在L尾部插入元素-1,21,13,24,8; (3)輸出順序表L; (4)輸出順序表L長度; (5)判斷順序表L是否為空; (6)輸出順序表L的第3個元素; (7)輸出元素24的位置; (8)在L的第4個元素前插入元素0; (9)輸出順序表L; (10)刪除L的第5個元素; (11)輸出順序表L。 源代碼 調試分析(給出運行結果界面) 二、編寫程序實現單鏈表的各種基本運算,并在此基礎上設計一個主程序完成如下功能: ???? ???? 小結或討論: (1)實驗中遇到的問題和解決方法 (2)實驗中沒有解決的問題 (3)體會和提高第三篇:數據結構實驗報告-排序與查找
第四篇:北郵數據結構實驗報告-排序
第五篇:數據結構實驗報告