資料結構與演算法——快速排序
快速排序介紹:
平均時間複雜度為O(NlogN),最壞的情況是O(N^2)。
快速排序是不穩定的,不能保證相等元素原來的排序順序。參考部落格:為什麼快速排序是不穩定的
原始碼:
/*************************************************************************
> File Name: quicksort.cpp
> Author:
> Mail:
> Created Time: 2016???1???2???星期???16???3???1???
************************************************************************/
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
//這是插入排序的演算法,用於排序數量小於10的序列
void insert_sort(vector<int> & data, int left, int right)
{
int j;
for (int i = left + 1; i <= right; ++i){
int tmp = data[i];
for (j = i; j > 0 && tmp < data[j-1]; j--){
data[j] = data[j-1];
}
data[j] = tmp;
}
}
//獲得樞紐元
template<class T>
const T & median3(vector<T> & a, int left, int right)
{
int center = (left+right)/2;
if(a[center] < a[left])
swap(a[center], a[left]);
if(a[right] < a[left])
swap(a[right], a[left]);
if(a[right] < a[center])
swap(a[center], a[right]);
//將樞紐元和最後一個元素互換位置
swap(a[center], a[right-1]);
return a[right-1];
}
//快速排序演算法
template<class T>
void quicksort(vector<T> & a, int left, int right)
{
//排序的元素的個數大於10,選擇快速排序,
if (left + 10 <= right){
T pivot = median3(a, left, right);//獲得樞紐元
//開始排序
int i = left, j = right - 1;
for ( ; ; ){
while(a[++i] < pivot){}
while(a[--j] > pivot){}
if(i < j)
swap(a[i], a[j]);
else
break;
}
swap(a[i], a[right-1]);//恢復樞紐元的位置
quicksort(a, left, i-1);
quicksort(a, i + 1, right);
}
else{
//排序的元素的個數小於10,用插入排序演算法來排序
insert_sort(a, left, right);
}
}
int main()
{
vector<int> v;
v.push_back(23);
v.push_back(12);
v.push_back(9);
v.push_back(34);
v.push_back(11);
v.push_back(7);
v.push_back(3);
v.push_back(10);
v.push_back(8);
v.push_back(25);
v.push_back(89);
v.push_back(11);
v.push_back(90);
v.push_back(100);
v.push_back(45);
v.push_back(28);
v.push_back(26);
cout << "v: ";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
quicksort(v, 0, v.size() -1);
cout << "quicksorted v: ";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
下面的例子是將陣列的第一個元素作為基準元素:
/*************************************************************************
> File Name: quicksort2.cpp
> Author:
> Mail:
> Created Time: 2016年04月17日 星期日 15時36分03秒
************************************************************************/
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace std;
//快速排序
void quickSort(vector<int> & v, int first, int last)
{
int value = v[first];//基準數字
if(first >= last)
return;
int i = first;
int j = last;
while(i < j){
while(v[j] >= value && i < j)
j--;
while(v[i] <= value && i < j)
i++;
swap(v[i], v[j]);
}
v[first] = v[i];//將中間的數字放入第一個位置,是為了將中間的數字作為基準數字
v[i] = value;//將基準數字重新中間
quickSort(v, first, i-1);
quickSort(v, i+1, last);
}
//主函式
int main()
{
srand(unsigned(time(0)));
vector<int> v;
for(int i = 0; i < 10; ++i)
v.push_back(rand()%10);
cout << "v: ";
for(int i = 0; i < 10; ++i)
cout << v[i] << " ";
cout << endl;
quickSort(v, 0, v.size()-1);
cout << "After sort: ";
for(int i = 0; i < 10; ++i)
cout << v[i] << " ";
cout << endl;
return 0;
}
while(v[j] >= value && i < j)
j--;
while(v[i] <= value && i < j)
i++;
這個順序一定不能反過來,必須先從右邊開始判斷。
程式輸出結果為:
v: 2 8 7 6 0 4 4 0 9 9
After sort: 0 0 2 4 4 6 7 8 9 9
root@linux_ever:~/linux_ever/algorithm/ch7# ./quicksort2
v: 2 4 3 4 5 4 0 8 8 7
After sort: 0 2 3 4 4 4 5 7 8 8
root@linux_ever:~/linux_ever/algorithm/ch7# ./quicksort2
v: 0 2 1 7 2 4 0 7 5 8
After sort: 0 0 1 2 2 4 5 7 7 8
root@linux_ever:~/linux_ever/algorithm/ch7# ./quicksort2
v: 9 2 1 1 7 9 1 8 8 9
After sort: 1 1 1 2 7 8 8 9 9 9
root@linux_ever:~/linux_ever/algorithm/ch7# ./quicksort2
v: 7 1 6 0 6 0 5 3 8 3
After sort: 0 0 1 3 3 5 6 6 7 8
root@linux_ever:~/linux_ever/algorithm/ch7# ./quicksort2
v: 7 1 6 0 6 0 5 3 8 3
After sort: 0 0 1 3 3 5 6 6 7 8
相關文章
- 資料結構與演算法之快速排序資料結構演算法排序
- python演算法與資料結構-快速排序(36)Python演算法資料結構排序
- 資料結構與演算法——排序資料結構演算法排序
- 資料結構與演算法 排序演算法 快速排序【詳細步驟圖解】資料結構演算法排序圖解
- C#資料結構與演算法5-C# 快速排序C#資料結構演算法排序
- 資料結構與演算法(八):排序資料結構演算法排序
- 資料結構與演算法之排序資料結構演算法排序
- 資料結構與演算法:堆排序資料結構演算法排序
- 【資料結構與演算法】堆排序資料結構演算法排序
- 資料結構與演算法——堆排序資料結構演算法排序
- 資料結構與演算法----# 一、排序資料結構演算法排序
- [資料結構與演算法] 排序演算法資料結構演算法排序
- 資料結構與演算法——排序演算法-歸併排序資料結構演算法排序
- 資料結構與演算法——排序演算法-基數排序資料結構演算法排序
- 資料結構與演算法——排序演算法-氣泡排序資料結構演算法排序
- 資料結構與演算法——排序演算法-選擇排序資料結構演算法排序
- 資料結構與演算法 排序與搜尋資料結構演算法排序
- 資料結構和演算法(Golang實現)(25)排序演算法-快速排序資料結構演算法Golang排序
- 資料結構與演算法 基礎排序資料結構演算法排序
- 資料結構與演算法 進階排序資料結構演算法排序
- Java資料結構與排序演算法 (三)Java資料結構排序演算法
- Java資料結構與排序演算法 (一)Java資料結構排序演算法
- Java資料結構與排序演算法 (二)Java資料結構排序演算法
- 資料結構與演算法-反轉排序資料結構演算法排序
- 【資料結構與演算法】歸併排序資料結構演算法排序
- 【資料結構與演算法】快速冪資料結構演算法
- 看圖輕鬆理解資料結構與演算法系列(快速排序)資料結構演算法排序
- 資料結構與演算法整理總結---排序 2資料結構演算法排序
- 資料結構與排序資料結構排序
- 資料結構和演算法面試題系列—排序演算法之快速排序資料結構演算法面試題排序
- 【Java資料結構與演算法】第八章 快速排序、歸併排序和基數排序Java資料結構演算法排序
- C語言版資料結構及演算法_快速排序C語言資料結構演算法排序
- 資料結構與演算法——十個排序演算法資料結構演算法排序
- 【演算法與資料結構】經典排序演算法總結演算法資料結構排序
- 演算法與資料結構之原地堆排序演算法資料結構排序
- 演算法與資料結構基礎 - 排序(Sort)演算法資料結構排序
- 演算法與資料結構高階排序演算法之歸併排序演算法資料結構排序
- 07 Javascript資料結構與演算法 之 排序演算法JavaScript資料結構演算法排序
- 【資料結構與演算法】非比較排序(計數排序、桶排序、基數排序)資料結構演算法排序