排序演算法之快速排序
阿新 • • 發佈:2018-12-20
快速排序:
通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字比另一部分記錄的關鍵字小,則可以分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
快速排序的時間複雜度,最好情況和平均情況為O(n * lgn ),最差情況下為O(n ^ 2),空間複雜度為O(lg n ), 是不穩定的排序演算法。
基本思想:分治演算法
找基準值的三種方式:
找邊上的(本文中程式碼均以最右邊為例) ;隨機選;三數取中
用基準值和陣列中的所有值進行比較,將比基準值小的都放到基準值的左邊,比基準值大的,放到基準值的右邊,三種方式:左右指標法;挖坑法;前後下標法
終止條件:小區間有序, 長度等於1;小區間內沒有數,長度等於0
左右指標法:
左右指標法:當begin停下來的時候,其值一定大於基準值 //左右指標法,左閉右閉區間[],將選的基準值放在最右邊, int Partion1(int arr[], int left, int right) { int pivot = arr[right]; int begin = left; int end = right; while(begin < end) { while(begin < end && arr[begin] <= pivot) { begin++; } if(begin == end) { break; } while(begin < end && arr[end] >= pivot) { end--; } if(begin == end) { break; } Swap(arr+begin, arr+end); } Swap(arr+begin, arr+right); return begin; }
挖坑法:
int Partion2(int arr[], int left, int right) { //left, right是不斷變化的 int pivot = arr[right]; int begin = left; int end = right; while(begin < end) { //如果基準值在最右邊,先移動begin while(begin < end && arr[begin] <= pivot) { begin++; } if(begin == end) { break; } //pivot已經標記了基準值,當arr[begin]的值大於基準值,則將arr[begin]更換到基準值的位置 //則在begin處留出一個空位,便於下一個數的填充 arr[end] = arr[begin]; while(begin < end && arr[end] >= pivot) { end--; } if(begin == end) { break; } //當end走到這一步,則將arr[end]取代原begin留下的空位 arr[begin] = arr[end]; } arr[begin] = pivot; //將基準值放到begin處。 return begin; }
前後指標法:
int Partion3(int arr[], int left, int right)
{
int pivot = arr[right];
int div = left;
int cur = left;
for(cur=left; cur<=right; cur++)
{
if(arr[cur] < pivot)
{
Swap(arr+cur, arr+div);
div++;
}
}
Swap(arr+right, arr+div);
return div;
}