常見排序演算法c++總結
總結一下常見的排序演算法,包括插入排序,氣泡排序,快速排序,
1.直接插入排序
整個序列分為有序區和無序區,取第一個元素作為初始有序區,然後第二個開始,依次插入到有序區的合適位置,直到排好序。
下面是具體程式碼實現:
void InsertSort2(vector<int> &num){ for(int i = 1;i < num.size();++i){ for(int j = i;j > 0;--j){ if(num[j] < num[j - 1]){ int temp = num[j]; num[j] = num[j-1]; num[j-1] = temp; } } } }
插入排序的時間複雜度最好的情況是已經是正序的序列,只需比較(n-1)次,時間複雜度為O(n),最壞的情況是倒序的序列,要比較n(n-1)/2次,時間複雜度為O(n^2 ) ,平均的話要比較時間複雜度為O(n^2 )。
插入排序是一種穩定的排序方法,排序元素比較少的時候很好,大量元素便會效率低下。
2.氣泡排序
比較相鄰的元素,如果反序則交換,過程也是分為有序區和無序區,初始時有序區為空,所有元素都在無序區,經過第一趟後就能找出最大的元素,然後重複便可。
氣泡排序感覺非常好理解,第一個for迴圈是遍歷所有元素,第二個for迴圈是每次遍歷元素時都對無序區的相鄰兩個元素進行一次比較,若反序則交換。
時間複雜度最壞的情況是反序序列,要比較n(n-1)/2次,時間複雜度為O(n^2 ),最好的情況是正序,只進行(n-1)次比較,不需要移動,時間複雜度為O(n),而平均的時間複雜度為O(n^2 )。
但是還有更好的方法,如果第一次比較完沒有交換即說明已經有序,不應該進行下一次遍歷。 還有已經遍歷出部分有序的序列後,那部分也不用進行遍歷,即發生交換的地方之後的地方不用遍歷。
void BubbleSort(int arr[], int len){ int i,temp; //記錄位置,當前所在位置和最後發生交換的地方 int current,last = len - 1; while(last > 0) { for(i = current = 0;i < last;++i){ if(arr[i] > arr[i+1]){ temp = arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; //記錄當前的位置,如果沒有發生交換current值即for迴圈初始化的0 current = i; } } //若current = 0即已經沒有可以交換的元素了,即已經有序了 last = current; } }
氣泡排序也是一種穩定的排序演算法,也是元素較少時效率比較高。
3.快速排序
快速排序首先選一個軸值(pivot,也有叫基準的),將待排序記錄劃分成獨立的兩部分,左側的元素均小於軸值,右側的元素均大於或等於軸值,然後對這兩部分再重複,直到整個序列有序。過程是和二叉搜尋樹相似,就是一個遞迴的過程。
//快速排序;
#include<iostream>
#include<algorithm>
using namespace std;
void Quick_sort(int a[],int left,int right) //快速排序;
{
if(left > right) return;
int i = left,j = right;
int base = a[left]; //記錄基準數;
while(i != j)
{
while(i < j && a[j] >= base) //先從基準數的對面開始找;
j--;
while(i < j && a[i] <= base) //再從另一邊找;
i++;
if(i < j) //在i和j未相遇時;
swap(a[i],a[j]); //交換兩個數;
}
swap(a[left],a[i]); //將基準數歸位;
Quick_sort(a,left,i-1); //處理左區間;
Quick_sort(a,i+1,right); //處理右區間;
}
這個圖不是一般的棒!!來自Wikipedia。
快速排序時間複雜度的最好情況和平均情況一樣為O(nlog2 n),最壞情況下為O(n^2 ),這個看起來比前面兩種排序都要好,但是這是不穩定的演算法,並且空間複雜度高一點( O(nlog2 n))。而且快速排序適用於元素多的情況。
未完待續...