日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

各排序算法的C++实现与性能测试(转)

發布時間:2025/5/22 c/c++ 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 各排序算法的C++实现与性能测试(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

排序是計算機算法中非常重要的一項,而排序算法又有不少實現方法,那么哪些排序算法比較有效率,哪些算法在特定場合比較有效,下面將用C++實現各種算法,并且比較他們的效率,讓我們對各種排序有個更深入的了解。

minheap.h 用于堆排序:

1 //使用時注意將關鍵碼加入 2 #ifndef MINHEAP_H 3 #define MINHEAP_H 4 #include <assert.h> 5 #include <iostream> 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 using std::cerr; 10 #include <stdlib.h> 11 //const int maxPQSize = 50; 12 template <class Type> class MinHeap { 13 public: 14 MinHeap ( int maxSize );//根據最大長度建堆 15 MinHeap ( Type arr[], int n );//根據數組arr[]建堆 16 ~MinHeap ( ) { delete [] heap; } 17 const MinHeap<Type> & operator = ( const MinHeap &R );//重載賦值運算符 18 int Insert ( const Type &x );//插入元素 19 int RemoveMin ( Type &x );//移除關鍵碼最小的元素,并賦給x 20 int IsEmpty ( ) const { return CurrentSize == 0; }//檢查堆是否為空 21 int IsFull ( ) const { return CurrentSize == MaxHeapSize; }//檢查對是否滿 22 void MakeEmpty ( ) { CurrentSize = 0; }//使堆空 23 private: 24 enum { DefaultSize = 50 };//默認堆的大小 25 Type *heap; 26 int CurrentSize; 27 int MaxHeapSize; 28 void FilterDown ( int i, int m );//自上向下調整堆 29 void FilterUp ( int i );//自下向上調整堆 30 }; 31 template <class Type> MinHeap <Type>::MinHeap ( int maxSize ) 32 { 33 //根據給定大小maxSize,建立堆對象 34 MaxHeapSize = (DefaultSize < maxSize ) ? maxSize : DefaultSize; //確定堆大小 35 heap = new Type [MaxHeapSize]; //創建堆空間 36 CurrentSize = 0; //初始化 37 } 38 template <class Type> MinHeap <Type>::MinHeap ( Type arr[], int n ) 39 { 40 //根據給定數組中的數據和大小,建立堆對象 41 MaxHeapSize = DefaultSize < n ? n : DefaultSize; 42 heap = new Type [MaxHeapSize]; 43 if(heap==NULL){cerr <<"fail" <<endl;exit(1);} 44 for(int i =0; i< n; i++) 45 heap[i] = arr[i]; //數組傳送 46 CurrentSize = n; //當前堆大小 47 int currentPos = (CurrentSize-2)/2; //最后非葉 48 while ( currentPos >= 0 ) { 49 //從下到上逐步擴大,形成堆 50 FilterDown ( currentPos, CurrentSize-1 ); 51 currentPos-- ; 52 //從currentPos開始,到0為止, 調整currentPos--; } 53 } 54 } 55 template <class Type> void MinHeap<Type>::FilterDown ( const int start, const int EndOfHeap ) 56 { 57 // 結點i的左、右子樹均為堆,調整結點i 58 int i = start, j = 2*i+1; // j 是 i 的左子女 59 Type temp = heap[i]; 60 while ( j <= EndOfHeap ) { 61 if ( j < EndOfHeap && heap[j] > heap[j+1] ) 62 j++;//兩子女中選小者 63 if ( temp<= heap[j] ) break; 64 else { heap[i] = heap[j]; i = j; j = 2*j+1; } 65 } 66 heap[i] = temp; 67 } 68 template <class Type> int MinHeap<Type>::Insert ( const Type &x ) 69 { 70 //在堆中插入新元素 x 71 if ( CurrentSize == MaxHeapSize ) //堆滿 72 { 73 cout << "堆已滿" << endl; return 0; 74 } 75 heap[CurrentSize] = x; //插在表尾 76 FilterUp (CurrentSize); //向上調整為堆 77 CurrentSize++; //堆元素增一 78 return 1; 79 } 80 template <class Type> void MinHeap<Type>::FilterUp ( int start ) 81 { 82 //從 start 開始,向上直到0,調整堆 83 int j = start, i = (j-1)/2; // i 是 j 的雙親 84 Type temp = heap[j]; 85 while ( j > 0 ) { 86 if ( (heap[i].root->data.key )<= (temp.root->data.key) ) break; 87 else { heap[j] = heap[i]; j = i; i = (i -1)/2; } 88 } 89 heap[j] = temp; 90 } 91 template <class Type> int MinHeap <Type>::RemoveMin ( Type &x ) 92 { 93 if ( !CurrentSize ) 94 { 95 cout << "堆已空 " << endl; 96 return 0; 97 } 98 x = heap[0]; //最小元素出隊列 99 heap[0] = heap[CurrentSize-1]; 100 CurrentSize--; //用最小元素填補 101 FilterDown ( 0, CurrentSize-1 ); 102 //從0號位置開始自頂向下調整為堆 103 return 1; 104 } 105 #endif

sort.cpp 主要的排序函數集包括冒泡排序、快速排序、插入排序、希爾排序、計數排序:

1 //n^2 2 //冒泡排序V[n]不參與排序 3 void BubbleSort (int V[], int n ) 4 { 5 bool exchange; //設置交換標志置 6 for ( int i = 0; i < n; i++ ){ 7 exchange=false; 8 for (int j=n-1; j>i; j--) { //反向檢測,檢查是否逆序 9 if (V[j-1] > V[j]) //發生逆序,交換相鄰元素 10 { 11 int temp=V[j-1]; 12 V[j-1]=V[j]; 13 V[j]=temp; 14 exchange=true;//交換標志置位 15 } 16 } 17 18 if (exchange == false) 19 return; //本趟無逆序,停止處理 20 } 21 } 22 //插入排序,L[begin],L[end]都參與排序 23 void InsertionSort ( int L[], const int begin, const int end) 24 { 25 //按關鍵碼 Key 非遞減順序對表進行排序 26 int temp; 27 int i, j; 28 for ( i = begin; i < end; i++ ) 29 { 30 if (L[i]>L[i+1]) 31 { 32 temp = L[i+1]; 33 j=i; 34 do 35 { 36 L[j+1]=L[j]; 37 if(j == 0) 38 { 39 j--; 40 break; 41 } 42 j--; 43 44 } while(temp<L[j]); 45 L[j+1]=temp; 46 } 47 } 48 } 49 //n*logn 50 //快速排序A[startingsub],A[endingsub]都參與排序 51 void QuickSort( int A[], int startingsub, int endingsub) 52 { 53 if ( startingsub >= endingsub ) 54 ; 55 else{ 56 int partition; 57 int q = startingsub; 58 int p = endingsub; 59 int hold; 60 61 do{ 62 for(partition = q ; p > q ; p--){ 63 if( A[q] > A[p]){ 64 hold = A[q]; 65 A[q] = A[p]; 66 A[p] = hold; 67 break; 68 } 69 } 70 for(partition = p; p > q; q++){ 71 if(A[p] < A[q]){ 72 hold = A[q]; 73 A[q] = A[p]; 74 A[p] = hold; 75 break; 76 } 77 } 78 79 }while( q < p ); 80 QuickSort( A, startingsub, partition - 1 ); 81 QuickSort( A, partition + 1, endingsub ); 82 } 83 } 84 //希爾排序,L[left],L[right]都參與排序 85 void Shellsort( int L[], const int left, const int right) 86 { 87 int i, j, gap=right-left+1; //增量的初始值 88 int temp; 89 do{ 90 gap=gap/3+1; //求下一增量值 91 for(i=left+gap; i<=right; i++) 92 //各子序列交替處理 93 if( L[i]<L[i-gap]){ //逆序 94 temp=L[i]; j=i-gap; 95 do{ 96 L[j+gap]=L[j]; //后移元素 97 j=j-gap; //再比較前一元素 98 }while(j>left&&temp<L[j]); 99 L[j+gap]=temp; //將vector[i]回送 100 } 101 }while(gap>1); 102 } 103 //n 104 //計數排序,L[n]不參與排序 105 void CountingSort( int L[], const int n ) 106 { 107 int i,j; 108 const int k =1001; 109 int tmp[k]; 110 int *R; 111 R = new int[n]; 112 for(i=0;i<k;i++) tmp[i]= 0; 113 for(j=0;j<n;j++) tmp[L[j]]++; 114 //執行完上面的循環后,tmp[i]的值是L中等于i的元素的個數 115 for(i=1;i<k;i++) 116 tmp[i]=tmp[i]+tmp[i-1]; //執行完上面的循環后, 117 //tmp[i]的值是L中小于等于i的元素的個數 118 for(j=n-1;j>=0;j--) //這里是逆向遍歷,保證了排序的穩定性 119 { 120 121 R[tmp[L[j]]-1] = L[j]; 122 //L[j]存放在輸出數組R的第tmp[L[j]]個位置上 123 tmp[L[j]]--; 124 //tmp[L[j]]表示L中剩余的元素中小于等于L[j]的元素的個數 125 126 } 127 for(j=0;j<n;j++) L[j] = R[j]; 128 } 129 //基數排序 130 void printArray( const int Array[], const int arraySize ); 131 int getDigit(int num, int dig); 132 const int radix=10; //基數 133 void RadixSort(int L[], int left, int right, int d){ 134 //MSD排序算法的實現。從高位到低位對序列劃分,實現排序。d是第幾位數,d=1是最低位。left和right是待排序元素子序列的始端與尾端。 135 int i, j, count[radix], p1, p2; 136 int *auxArray; 137 int M = 5; 138 auxArray = new int[right-left+1]; 139 if (d<=0) return; //位數處理完遞歸結束 140 if (right-left+1<M){//對于小序列可調用直接插入排序 141 InsertionSort(L,left,right); return; 142 } 143 for (j=0; j<radix; j++) count[j]=0; 144 for (i=left; i<=right; i++) //統計各桶元素的存放位置 145 count[getDigit(L[i],d)]++; 146 for (j=1; j<radix; j++) //安排各桶元素的存放位置 147 count[j]=count[j]+count[j-1]; 148 for (i=right; i>=left; i--){ //將待排序序列中的元素按位置分配到各個桶中,存于助數組auxArray中 149 j=getDigit(L[i],d); //取元素L[i]第d位的值 150 auxArray[count[j]-1]=L[i]; //按預先計算位置存放 151 count[j]--; //計數器減1 152 } 153 for (i=left, j=0; i<=right; i++, j++) 154 L[i]=auxArray[j]; //從輔助數組順序寫入原數組 155 delete []auxArray; 156 for (j=0; j<radix; j++){ //按桶遞歸對d-1位處理 157 p1=count[j]+left; //取桶始端,相對位置,需要加上初值$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 158 (j+1 <radix )?(p2=count[j+1]-1+left):(p2=right) ; //取桶尾端 159 // delete []count; 160 if(p1<p2){ 161 RadixSort(L, p1, p2, d-1); //對桶內元素進行基數排序 162 // printArray(L,10); 163 } 164 } 165 166 } 167 int getDigit(int num, int dig) 168 { 169 int myradix = 1; 170 /* for(int i = 1;i<dig;i++) 171 { 172 myradix *= radix; 173 }*/ 174 switch(dig) 175 { 176 case 1: 177 myradix = 1; 178 break; 179 case 2: 180 myradix = 10; 181 break; 182 case 3: 183 myradix = 1000; 184 break; 185 case 4: 186 myradix = 10000; 187 break; 188 default: 189 myradix = 1; 190 break; 191 } 192 return (num/myradix)%radix; 193 }

maintest.cpp 測試例子:

1 #include<iostream> 2 using std::cout; 3 using std::cin; 4 using std::endl; 5 #include <cstdlib> 6 #include <ctime> 7 #include<iostream> 8 using std::cout; 9 using std::cin; 10 using std::ios; 11 using std::cerr; 12 using std::endl; 13 #include<iomanip> 14 using std::setw; 15 using std::fixed; 16 #include<fstream> 17 using std::ifstream; 18 using std::ofstream; 19 using std::flush; 20 #include<string> 21 using std::string; 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <time.h> 25 #include"minheap.h" 26 void BubbleSort(int arr[], int size);//冒泡排序 27 void QuickSort( int A[], int startingsub, int endingsub);//快速排序 28 void InsertionSort ( int L[], const int begin,const int n);//插入排序 29 void Shellsort( int L[], const int left, const int right);//希爾排序 30 void CountingSort( int L[], const int n );//計數排序 31 int getDigit(int num, int dig);//基數排序中獲取第dig位的數字 32 void RadixSort(int L[], int left, int right, int d);//基數排序 33 void printArray( const int Array[], const int arraySize );//輸出數組 34 int main() 35 { 36 clock_t start, finish; 37 double duration; 38 /* 測量一個事件持續的時間*/ 39 ofstream *ofs; 40 string fileName = "sortResult.txt"; 41 ofs = new ofstream(fileName.c_str(),ios::out|ios::app); 42 const int size = 100000; 43 int a[size]; 44 int b[size]; 45 srand(time(0)); 46 ofs->close(); 47 for(int i = 0; i < 20;i++) 48 { 49 ofs->open(fileName.c_str(),ios::out|ios::app); 50 if( ofs->fail()){ 51 cout<<"!!"; 52 ofs->close(); 53 } 54 for(int k =0; k <size;k++) 55 { 56 a[k] = rand()%1000; 57 b[k] = a[k]; 58 59 } 60 /* for( k =0; k <size;k++) 61 { 62 a[k] = k; 63 b[k] = a[k]; 64 65 } */ 66 //printArray(a,size); 67 //計數排序 68 for( k =0; k <size;k++) 69 { 70 a[k] = b[k]; 71 } 72 start = clock(); 73 CountingSort(a,size); 74 75 finish = clock(); 76 // printArray(a,size); 77 78 duration = (double)(finish - start) / CLOCKS_PER_SEC; 79 printf( "%s%f seconds\n", "計數排序:",duration ); 80 *ofs<<""<<i<<"次:\n " <<"排序內容:0~999共" << size << " 個整數\n" ; 81 *ofs<<""<<i<<"次計數排序:\n " <<" Time: " <<fixed<< duration << " seconds\n"; 82 //基數排序 83 for( k =0; k <size;k++) 84 { 85 a[k] = b[k]; 86 } 87 start = clock(); 88 RadixSort(a, 0,size-1, 3); 89 finish = clock(); 90 // printArray(a,size); 91 92 duration = (double)(finish - start) / CLOCKS_PER_SEC; 93 printf( "%s%f seconds\n", "基數排序:",duration ); 94 *ofs<<""<<i<<"次基數排序:\n " <<" Time: " << duration << " seconds\n"; 95 //堆排序 96 MinHeap<int> mhp(a,size); 97 start = clock(); 98 for( k =0; k <size;k++) 99 { 100 mhp.RemoveMin(a[k]); 101 } 102 finish = clock(); 103 // printArray(a,size); 104 duration = (double)(finish - start) / CLOCKS_PER_SEC; 105 printf( "%s%f seconds\n", "堆排序:",duration ); 106 *ofs<<""<<i<<"次堆排序:\n " <<" Time: " << duration << " seconds\n"; 107 //快速排序 108 for( k =0; k <size;k++) 109 { 110 a[k] = b[k]; 111 112 } 113 //printArray(a,size); 114 start = clock(); 115 QuickSort(a,0,size-1); 116 finish = clock(); 117 // printArray(a,size); 118 duration = (double)(finish - start) / CLOCKS_PER_SEC; 119 printf( "%s%f seconds\n", "快速排序:",duration ); 120 *ofs<<""<<i<<"次快速排序:\n " <<" Time: " << duration << " seconds\n"; 121 //希爾排序 122 for( k =0; k <size;k++) 123 { 124 a[k] = b[k]; 125 } 126 start = clock(); 127 Shellsort(a,0,size-1); 128 129 finish = clock(); 130 // printArray(a,size); 131 132 duration = (double)(finish - start) / CLOCKS_PER_SEC; 133 printf( "%s%f seconds\n", "希爾排序:",duration ); 134 *ofs<<""<<i<<"次希爾排序:\n " <<" Time: " << duration << " seconds\n"; 135 136 //插入排序 137 for( k =0; k <size;k++) 138 { 139 a[k] = b[k]; 140 } 141 start = clock(); 142 InsertionSort (a,0,size-1); 143 finish = clock(); 144 // printArray(a,size); 145 146 duration = (double)(finish - start) / CLOCKS_PER_SEC; 147 printf( "%s%f seconds\n", "插入排序:",duration ); 148 *ofs<<""<<i<<"次插入排序:\n " <<" Time: " << duration << " seconds\n"; 149 //冒泡排序 150 for( k =0; k <size;k++) 151 { 152 a[k] = b[k]; 153 } 154 start = clock(); 155 BubbleSort(a,size); 156 finish = clock(); 157 // printArray(a,size); 158 159 duration = (double)(finish - start) / CLOCKS_PER_SEC; 160 printf( "%s%f seconds\n", "冒泡排序:",duration ); 161 *ofs<<""<<i<<"次冒泡排序:\n " <<" Time: " << duration << " seconds\n"; 162 ofs->close(); 163 } 164 return 0; 165 } 166 void printArray( const int Array[], const int arraySize ) 167 { 168 for( int i = 0; i < arraySize; i++ ) { 169 cout << Array[ i ] << " "; 170 if ( i % 20 == 19 ) 171 cout << endl; 172 } 173 cout << endl; 174 }

排序算法性能仿真:

排序內容:從0~999中隨機產生,共100000 個整數,該表中單位為秒。

次數計數排序基數排序堆排序快速排序希爾排序直接插入排序冒泡排序
10.00000.03100.04700.04700.031014.797058.0930
20.00000.04700.03100.04700.047016.250053.3280
30.00000.03100.03100.03100.031014.485062.4380
40.00000.03200.03200.04700.031017.109061.8440
50.00000.03100.04700.04700.031016.938062.3280
60.00000.03100.03100.04700.031016.938057.7030
70.00000.03100.04700.03100.031016.875061.9380
80.01500.04700.03100.04700.032017.391062.8600
90.00000.03200.04700.04600.031016.953062.2660
100.00000.04700.03100.04700.031017.016060.1410
110.00000.09300.07800.03200.031014.609054.6570
120.00000.03100.03200.03100.031015.094062.3430
130.00000.03100.03100.04700.031017.234061.9530
140.00000.03200.04700.04700.031016.906061.0620
150.00000.03200.03200.04600.032016.781062.5310
160.00000.04700.04700.06200.031017.235057.1720
170.01500.01600.03200.04700.031014.140052.0320
180.01500.01600.03100.03100.031014.110052.3590
190.00000.03100.03200.04600.032014.109051.8750
200.00000.03100.03200.04600.032014.078052.4840
210.01500.07800.04700.04700.031016.375059.5150
220.00000.03100.03100.04700.032016.890060.3440
230.00000.03100.03100.03100.031016.344060.0930
240.00000.03100.03100.04700.031016.344060.5780
250.00000.03200.04700.04700.047016.359059.7810
260.01600.04700.03100.04700.031016.125061.0620
270.00000.03100.04700.04700.031016.781059.6100
280.01500.03200.03200.04700.031016.922056.8130
290.00000.03100.03100.03100.031015.079057.8120
300.00000.03100.03200.04600.032014.781058.8280
310.00000.03100.03100.04700.031015.859059.1400
320.00000.04700.03200.03100.031016.094059.1560
330.00000.04700.03100.03100.031015.985059.1400
340.00000.03100.03100.04700.032016.015059.2500
350.00000.03100.04700.04700.031016.766057.9840
360.00000.03100.03200.04700.031015.375059.0470
370.00000.03200.04600.04700.032016.031058.9060
380.00000.03100.03100.04700.031015.953057.2650
390.01600.03100.04700.04700.031015.953057.5160
400.01500.03100.03200.04700.031014.703056.6710
平均值0.00310.03600.03720.04370.032015.994658.7480
最小值0.00000.01600.03100.03100.031014.078051.8750
最大值0.01600.09300.07800.06200.047017.391062.8600

?

?from:http://www.nowamagic.net/librarys/veda/detail/294

轉載于:https://www.cnblogs.com/bizhu/archive/2012/08/12/2634340.html

總結

以上是生活随笔為你收集整理的各排序算法的C++实现与性能测试(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。