昨天去面試小企鵝的時候,被讓10分鐘寫排序,演算法隨意。當時有感排序演算法還不夠十分熟練,快排、堆排、歸併這些根本往上寫,怕哪裡出問題。所以回來後,默著把七種內排序寫了幾次,鞏固基礎,以後爭取10分鐘三種簡單,半小時寫七種排序。
C/C++源碼:Sort.cpp
#include <iostream><br />#include <cassert><br />#include <stack><br />#include <cstring><br />using namespace std;</p><p>void bubble(int A[],int n);<br />void select(int A[],int n);<br />void insert(int A[],int n);<br />void shell(int A[],int n);<br />void quick(int A[],int n);<br />void heap(int A[],int n);<br />void merge(int A[],int n);<br />typedef void (*FUNC)(int A[],int n);<br />FUNC Sort_func[]={bubble,select,insert,shell,quick,heap,merge};<br />const int Sort_num = sizeof(Sort_func)/sizeof(FUNC);<br />string Sort_name[]={"bubble","select","insert","shell","quick","heap","merge"};<br />const int N = 1024*1024*1024;<br />const int NUMS_PER_LINE = 10;</p><p>int main(int argc, char *argv[])<br />{<br /> string input("data.txt"), output("sort_output_");<br /> if(argc==2){<br /> input = argv[1];<br /> }else if(argc==3){<br /> input = argv[1];<br /> output = argv[2];<br /> }<br /> FILE *fptr=NULL;<br /> if((fptr=fopen(input.c_str(),"r"))!=NULL){<br /> int *arr1=NULL, *arr2=NULL;<br /> arr1 = new int[N];<br /> arr2 = new int[N];<br /> if(arr1==NULL){<br /> cout << "new arr1 failed" << endl;<br /> fclose(fptr);<br /> }else if(arr2==NULL){<br /> cout << "new arr2 failed" << endl;<br /> fclose(fptr);<br /> }else{<br /> int data, i=0;<br /> while(fscanf(fptr,"%d",&data)!=EOF){<br /> arr1[i++]=data;<br /> }<br /> fclose(fptr);<br /> for(int c=Sort_num-1;c>=0;c--){<br /> memmove(arr2,arr1,sizeof(int)*i);<br /> clock_t s,f;<br /> double timeUsed = 0.0;<br /> s = clock();<br /> (*Sort_func[c])(arr2,i);<br /> f = clock();<br /> timeUsed = (double)(f-s)/CLOCKS_PER_SEC;<br /> cout << Sort_name[c] << ":/t" << timeUsed << "s" << endl;<br /> assert(c>=0&&c<=9);<br /> if((fptr=fopen((output+(char)(c+'0')).c_str(),"w"))!=NULL){<br /> for(int j=0;j<i;j++){<br /> fprintf(fptr,"%d/t", arr2[j]);<br /> if(j%NUMS_PER_LINE==NUMS_PER_LINE-1)<br /> fprintf(fptr,"/n");<br /> }<br /> fclose(fptr);<br /> }else{<br /> cout << "Can't write outfile /"" << output << "/"" << endl;<br /> }<br /> }<br /> }<br /> }else{<br /> cout << "Can't open input file /"" << input << "/"" << endl;<br /> }<br /> return 0;<br />}</p><p>void swap(int& a,int& b){<br /> int tmp=a;<br /> a = b;<br /> b = tmp;<br />}<br />void bubble(int A[],int n){<br /> for(int i=1;i<n;i++)<br /> for(int j=1;j<=n-i;j++)<br /> if(A[j]<A[j-1])<br /> swap(A[j],A[j-1]);<br />}<br />void select(int A[],int n){<br /> for(int i=0;i<n-1;i++){<br /> int min = i;<br /> for(int j=i+1;j<n;j++){<br /> if(A[j]<A[min])<br /> min = j;<br /> }<br /> swap(A[i],A[min]);<br /> }<br />}<br />void insert(int A[],int n){<br /> for(int i=1,j;i<n;i++){<br /> int tmp = A[i];<br /> for(j=0;j<i && A[j]<=tmp;j++)<br /> ;<br /> for(int k=i-1;k>=j;k--)<br /> A[k+1]=A[k];<br /> A[j]=tmp;<br /> }<br />}<br />void shell(int A[],int n){<br /> int h;<br /> for(h=1;h<n/9;h=3*h+1);<br /> for(;h>0;h/=3){<br /> for(int i=h,j;i<n;i+=h){<br /> int tmp = A[i];<br /> for(j=0;j<i && A[j]<=tmp;j+=h);<br /> for(int k=i-h;k>=j;k-=h)<br /> A[k+h]=A[k];<br /> A[j]=tmp;<br /> }<br /> }<br />}</p><p>struct node{<br /> node(int a,int b):l(a),r(b){}<br /> int l,r;<br />};<br />void quick(int A[],int n){<br /> stack<node*> s;<br /> s.push(new node(0,n-1));<br /> while(!s.empty()){<br /> int l=s.top()->l;<br /> int r=s.top()->r;<br /> s.pop();<br /> if(l<r){<br /> int i=l, j=r;<br /> int pivot = A[l];<br /> while(i<j){<br /> while(A[i]<=pivot && i<=j) i++;<br /> while(A[j]>=pivot && i<=j) j--;<br /> if(i<j) swap(A[i],A[j]);<br /> }<br /> swap(A[l],A[j]);<br /> if(j-1-l>0) s.push(new node(l,j-1));<br /> if(r-j-1>0) s.push(new node(j+1,r));<br /> }<br /> }<br />}<br />void heapify(int A[],int i, int n){<br />#define LC(i) (2*i+1)<br />#define RC(i) (2*i+2)<br />#define PAR(i) ((i-1)/2)<br /> if(i<n/2){<br /> int max = A[i], f = 0;<br /> if(max < A[LC(i)] && LC(i) < n) max = A[LC(i)], f = 1;<br /> if(max < A[RC(i)] && RC(i) < n) f = 2;<br /> if(1==f){<br /> swap(A[i],A[LC(i)]);<br /> heapify(A,LC(i),n);<br /> }else if(2==f){<br /> swap(A[i],A[RC(i)]);<br /> heapify(A,RC(i),n);<br /> }<br /> }<br />}<br />void heap(int A[],int n){<br /> if(n<=1) return;<br /> for(int i=n/2-1;i>=0;i--)<br /> heapify(A,i,n);<br /> swap(A[0],A[n-1]);<br /> for(int i=n-2;i>=1;i--){<br /> heapify(A,0,i+1);<br /> swap(A[0],A[i]);<br /> }<br />}<br />void merge1(int A[],int l, int r){<br /> if(l<r){<br /> int mid = (r-l)/2+l;<br /> merge1(A,l,mid);<br /> merge1(A,mid+1,r);<br /> int *bak = new int[r-l+1];<br /> int i=0,j=l,k=mid+1;<br /> while(j<=mid && k<=r)<br /> bak[i++]=(A[j]<A[k]?A[j++]:A[k++]);<br /> while(j<=mid) bak[i++]=A[j++];<br /> while(k<=r) bak[i++]=A[k++];<br /> memmove(A+l,bak,sizeof(int)*i);<br /> }<br />}<br />void merge(int A[],int n){<br /> merge1(A,0,n-1);<br />}</p><p>
C/C++源碼:data.cpp
用來產生一定規模的隨機資料,測試排序
#include <iostream><br />#include <cstring><br />#include <ctime><br />#include <cstdlib><br />using namespace std;</p><p>long long cal(char s[]){<br /> long long sum =0;<br /> int len = strlen(s);<br /> for(int i=0;i<len;i++){<br /> sum += sum*9 + (s[i]-'0');<br /> }<br /> return sum;<br />}</p><p>const int NAME_LEN = 128;<br />const int N = 1024*1024;<br />int main(int argc, char *argv[])<br />{<br /> srand(time(NULL));<br /> long long scale = 10000;<br /> char filename[NAME_LEN] = "data.txt";</p><p> if(argc==2){<br /> scale = cal(argv[1]);<br /> }else if(argc ==3){<br /> scale = cal(argv[1]);<br /> strcpy(filename,argv[2]);<br /> }<br /> FILE *fptr = NULL;<br /> if((fptr=fopen(filename,"w"))!=NULL){<br /> for(long long i=0;i<scale;i++){<br /> fprintf(fptr, "%d/t", rand()%N);<br /> if(i%10==9)<br /> fprintf(fptr, "/n");<br /> }<br /> }else{<br /> cout << "Can't write file" << endl;<br /> }<br /> return 0;<br />}<br />
用data產生10W的隨機資料,已耗用時間如下:
當運行已經有序的10W資料時,已耗用時間如下:
運行100W隨機資料集時,已耗用時間如下:
運行100隨機資料集,並且每種演算法運行1024*16次,已耗用時間如下:
運行10隨機資料,並且每種演算法運行1024*128次,已耗用時間如下: