c++內部排序演算法
阿新 • • 發佈:2019-01-02
#include <iostream> using namespace std; /* *<<直接插入排序>> * 為了實現N個數的排序,將後面N-1個數依次插入到前面已排好的子序列中, *假定剛開始第1個數是一個已排好序的子序列。經過N-1趟就能得到一個有序序列。 *****時間複雜度:最好情況O(n),最壞情況O(n^2),平均情況O(n^2). *****空間複雜度:O(1) *****穩定性:穩定 */ void InsertSort( int* p, int nLen ) { int nTemp; for(int i=1; i<nLen; ++i) { nTemp = *(p+i); for(int j=i; j>0; --j) { if( nTemp < *(p+j-1) ) { *(p+j) = *(p+j-1); *(p+j-1) = nTemp; }else{ break; } } } } /* *<<折半插入排序>> * 與直接插入排序不同的是,折半插入排序不是邊比較邊移動,而是將比較和移 *動操作分離出來,即先折半查找出元素的待插入位置,然後再統一地移動待插入位 *置之後的所有元素。不難看出折半插入排序僅僅是減少了比較的次數。 *****時間複雜度:O(n^2) *****空間複雜度:O(1) *****穩定性:穩定 */ void BinaryInsertSort( int arr[], int nLen ) { int nHigh,nLow,nMid,i,j,nTemp; for(i=1; i<nLen; ++i) { nTemp = arr[i]; nLow = 0; nHigh = i-1; while( nLow<=nHigh) { nMid = (nLow+nHigh)/2; if(arr[nMid]>nTemp) { nHigh = nMid-1; }else{ nLow = nMid+1; } } for(j=i; j>nMid; --j) { arr[j] = arr[j-1]; } arr[nMid] = nTemp; } } /* *<<希爾排序>> * 希爾排序通過比較相距一定間隔的元素,即形如L[i,i+d,i+2d,...i+kd]的序列 *然後縮小間距,再對各分組序列進行排序。直到只比較相鄰元素的最後一趟排序為 *止,即最後的間距為1。希爾排序有時也叫做*縮小增量排序* *****時間複雜度:依賴於增量序列的選擇,但最壞情況才為O(N^2) *****空間複雜度:O(1) *****穩定性:不穩定 */ void ShellSort( int arr[], int nLen ) { int i, j, dk; int nTemp; for(dk=nLen/2; dk>0; dk/=2) { for(i=dk; i<nLen; ++i) { nTemp = arr[i]; for(j=i-dk; j>=0; j-=dk) { if(arr[j]>nTemp) { arr[j+dk] = arr[j]; arr[j] = nTemp; } } } } } /* *<<氣泡排序>> * 氣泡排序的基本思想是從後往前(或從前往後)兩兩比較相鄰元素的值,若為 *逆序,則交換它們,直到序列比較完。我們稱它為一趟冒泡。每一趟冒泡都會將一 *個元素放置到其最終位置上。 *****時間複雜度:最好情況O(n),最壞情況O(n^2),平均情況O(n^2) *****空間複雜度:O(1) *****穩定性:穩定 */ void BubbleSort( int arr[], int nLen ) { bool flag = false; for(int i=0; i<nLen-1; ++i) { flag = false; for(int j=nLen-1; j>i; --j) { if(arr[j-1]>arr[j]) { flag = true; arr[j-1] = arr[j-1]^arr[j]; arr[j] = arr[j-1]^arr[j]; arr[j-1] = arr[j-1]^arr[j]; } } if( !flag ) { return; } } } /* *<<快速排序>> * 快速排序是對氣泡排序的一種改進。其基本思想是基於分治法:在待排序表L[n] *中任取一個元素pivot作為基準,通過一趟排序將序列劃分為兩部分L[1...K-1]和 *L[k+1...n],是的L[1...k-1]中的所有元素都小於pivot,而L[k+1...n]中所有元素 *都大於或等於pivot。則pivot放在了其最終位置L(k)上。然後,分別遞迴地對兩個子 *序列重複上述過程,直至每部分內只有一個元素或空為止,即所有元素放在了其最終 *位置上。 *****時間複雜度:快排的執行時間與劃分是否對稱有關,最壞情況O(n^2),最好情況 *O(nlogn),平均情況為O(nlogn) *****空間複雜度:由於需要遞迴工作棧,最壞情況為O(n),平均情況為O(logn) *****穩定性:不穩定 */ int Partition(int a[], int low, int high) { int pivot = a[low]; while(low<high) { while(low<high && a[high]>=pivot) { --high; } a[low] = a[high]; while(low<high && a[low]<=pivot) { ++low; } a[high] = a[low]; } a[low] = pivot; return low; } void QuickSort(int a[], int low, int high) { if(low<high) { int pivotPos = Partition(a, low, high); QuickSort(a, low, pivotPos-1); QuickSort(a, pivotPos+1, high); } } /* *<<簡單選擇排序>> * 選擇排序的演算法思想很簡單,假設序列為L[n],第i趟排序即從L[i...n]中選擇 *關鍵字最小的元素與L(i)交換,每一趟排序可以確定一個元素的最終位置。經過n-1 *趟排序就可以使得序列有序了。 *****時間複雜度:始終是O(n^2) *****空間複雜度:O(1) *****穩定性:不穩定 */ void SelectedSort( int a[], int n ) { for(int i=0; i<n-1; ++i) { int minPos = i; for(int j=i+1; j<n; ++j) { if(a[j]<a[minPos]) { minPos = j; } } if( minPos != i) { a[i]=a[i]^a[minPos]; a[minPos]=a[i]^a[minPos]; a[i]=a[i]^a[minPos]; } } } /* *<<堆排序>> * 堆排序是一種樹形選擇排序方法,在排序過程中,將L[n]看成是一棵完全二叉 *樹的順序儲存結構,利用完全二叉樹中雙親節點和孩子節點之間的內在關係,在當 *前無序區中選擇關鍵字最大(或最小)的元素。堆排序的思路是:首先將序列L[n] *的n個元素建成初始堆,由於堆本身的特點(以大根堆為例),堆頂元素就是最大 *值。輸出堆頂元素後,通常將堆底元素送入堆頂,此時根結點已不滿足大根堆的性 *質,堆被破壞,將堆頂元素向下調整使其繼續保持大根堆的性質,再輸出堆頂元素。 *如此重複,直到堆中僅剩下一個元素為止。 *****時間複雜度:O(nlogn) *****空間複雜度:O(1) *****穩定性:不穩定 */ void AdjustUp( int arr[], int i, int nLen ) { int nTemp = arr[i]; for(int largest=2*i+1; largest<nLen; largest=2*largest+1) { if(largest!=nLen-1 && arr[largest]>arr[largest+1]) ++largest; if( nTemp > arr[largest] ) { arr[i] = arr[largest]; i = largest; }else{ break; } } arr[i] = nTemp; } void BuildHeap( int arr[], int nLen ) { for(int i=nLen/2-1; i>=0; --i) AdjustUp(arr,i,nLen); } void SortHeap( int arr[], int nLen) { BuildHeap(arr, nLen); for(int i=nLen-1; i>0; --i)// n-1趟的交換和建堆過程 { arr[0] = arr[0]^arr[i]; arr[i] = arr[0]^arr[i]; arr[0] = arr[0]^arr[i]; AdjustUp(arr, 0, i); } } int main( int argc, char *argv[]) { int arr[] = {9,6,7,4,2,5,3,1,8}; int nLen = sizeof(arr)/sizeof(int); //InsertSort(arr, nLen); //BinaryInsertSort(arr, nLen); //ShellSort(arr, nLen); //BubbleSort(arr, nLen); //SortHeap(arr, nLen); // SelectedSort(arr,nLen); QuickSort(arr, 0, nLen-1); for(int i=0; i<nLen; ++i) { cout<<*(arr+i)<<' '; }cout<<endl; return 0; }