資料結構實踐 大資料集上排序演算法效能的體驗

2021-09-23 18:00:16 字數 4158 閱讀 3381

本文是針對[資料結構基礎系列(9):排序]的實踐專案。

【專案 - 大資料集上排序演算法效能的體驗】

設計乙個函式,產生乙個至少5萬條記錄的資料集合。在同一資料集上,用直接插入排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序等演算法進行排序,記錄所需要的時間,經過對比,得到對複雜度不同的各種演算法在執行時間方面的感性認識。

提示1:這一專案需要整合多種排序演算法,可以考慮先建設排序演算法庫,作為我們這門課演算法庫的收官之作;

提示2:本專案旨在獲得對於複雜度不同演算法的感性認識,由於資料分布特點、計算機執行狀態等不同,其結果並不能完全代替對演算法複雜度的理論分析;

提示3:由於c語言標準提供的時間函式只精確到秒,幾種o(

nlog

2n) 

級別的演算法,在5萬條記錄的壓力下,並不能明顯地看出優劣,可以忽略直接插入排序、氣泡排序、直接選擇排序這三種相對低效率的演算法(以節約時間。若能夠忍受他們長時間地執行,請自便。),成10倍地加大資料量,然後進行觀察。

[參考解答]

1.測試用的主控程式——main.cpp

#include 

#include

#include

#include

#include "sort.h"

void getlargedata(rectype *&r, int n)

//呼叫某一排序演算法完成排序,返回排序用時

long sort(rectype *&r, int n, void f(rectype*,

int))

//呼叫基數排序演算法完成排序,返回排序用時

long sort1(rectype *&r, int n)

int main()

2.標頭檔案 —— sort.h

#ifndef sort_h_included

#define sort_h_included

#define maxsize 50000 //最多的資料,取5萬,只測試快速演算法,可以往大調整

//下面的符號常量和結構體針對基數排序

#define radix 10 //基數的取值

#define digits 10 //關鍵字位數

typedef

int keytype; //定義關鍵字型別

typedef

char infotype[10];

typedef

struct

//記錄型別

rectype; //排序的記錄型別定義

typedef

struct node

radixrectype;

void insertsort(rectype r,int n); //直接插入排序

void shellsort(rectype r,int n); //希爾排序演算法

void bubblesort(rectype r,int n); //氣泡排序

void quicksort(rectype r,int n); //快速排序

void selectsort(rectype r,int n); //直接選擇排序

void heapsort(rectype r,int n); //堆排序

void mergesort(rectype r,int n); //歸併排序

//下面函式支援基數排序

void createlink(radixrectype *&p,rectype r,int n); //建立基數排序用的鍊錶

void destorylink(radixrectype *&p); //釋放基數排序用的鍊錶

void radixsort(radixrectype *&p); //基數排序

#endif // sort_h_included

3.演算法的實現—— sort.cpp

#include "sort.h"

#include

//1. 對r[0..n-1]按遞增有序進行直接插入排序

void insertsort(rectype r,int n)

r[j+1]=tmp; //在j+1處插入r[i]

}}//2. 希爾排序演算法

void shellsort(rectype r,int n)

r[j+gap]=tmp;

j=j-gap;

}gap=gap/2; //減小增量

}}//3. 氣泡排序

void bubblesort(rectype r,int n)

if (exchange==0) //沒有交換,即結束演算法

return;

}}//4. 對r[s]至r[t]的元素進行快速排序

void quicksortr(rectype r,int s,int t)

r[i]=tmp;

quicksortr(r,s,i-1); //對左區間遞迴排序

quicksortr(r,i+1,t); //對右區間遞迴排序

}}//4. 快速排序輔助函式,對外同其他演算法統一介面,內部呼叫遞迴的快速排序

void quicksort(rectype r,int n)

//5. 直接選擇排序

void selectsort(rectype r,int n)

}}//6. 堆排序輔助之——調整堆

void sift(rectype r,int low,int high)

else

break; //篩選結束

}r[i]=temp; //被篩選結點的值放入最終位置

}//6. 堆排序

void heapsort(rectype r,int n)

}//7.歸併排序輔助1——合併有序表

void merge(rectype r,int low,int mid,int high)

else

//將第2段中的記錄放入r1中

while (i<=mid) //將第1段餘下部分複製到r1

while (j<=high) //將第2段餘下部分複製到r1

for (k=0,i=low; i<=high; k++,i++) //將r1複製回r中

r[i]=r1[k];

}//7. 歸併排序輔助2——一趟歸併

void mergepass(rectype r,int

length,int n) //對整個數序進行一趟歸併

//7. 歸併排序

void mergesort(rectype r,int n) //自底向上的二路歸併演算法

//以下基數排序,為了統一測試有改造

//8. 基數排序的輔助函式,建立基數排序用的鍊錶

void createlink(radixrectype *&p,rectype r,int n) //採用後插法產生鍊錶

else

}t->next=null;

}//8. 基數排序的輔助函式,釋放基數排序用的鍊錶

void destorylink(radixrectype *&p)

return;

}//8. 實現基數排序:*p為待排序序列鍊錶指標,基數r和關鍵字位數d已經作為符號常量定義好

void radixsort(radixrectype *&p)

else

p=p->next; //取下乙個待排序的元素

}p=null; //重新用p來收集所有結點

for (j=0; j//對於每乙個鏈隊迴圈

if (head[j]!=null) //進行收集

else

}t->next=null; //最後乙個結點的next域置null

//下面更新用於分離出第i位數字的d2

d2*=10;

}}

第十六周實踐專案2 大資料集上排序演算法效能的體驗

檔名稱 專案2.cbp 作 者 劉晨筱 完成日期 2015年12月14日 版 本 號 v1.0 問題描述 設計乙個函式,產生乙個至少5萬條記錄的資料集合。在同一資料集上,用直接插入排序 氣泡排序 快速排序 直接選擇排序 堆排序 歸併排序 基數排序等演算法進行排序,記錄所需要的時間,經過對比,得到對複...

專案2 大資料集上排序演算法效能的體驗

檔名稱 main.cpp 完成日期 2015年12月14日 版本號 codeblocks 問題描述 設計乙個函式,產生乙個至少5萬條記錄的資料集合。在同一資料集上,用直接插入排序 氣泡排序 快速排序 直接選擇排序 堆排序 歸併排序 基數排序等演算法進行排序,記錄所需要的時間,經過對比,得到對複雜度不...

資料結構 演算法實踐 排序 選擇排序 選擇排序

回主目錄 排序 選擇排序 選擇排序 list 0.概念 偽 示例分析 1.選擇排序實現 2.question 0 start 基本概念 維基百科 偽 function selectsort a list 1.n swap a index a max index 將最大的換到後面 index inde...