排序演算法之「快速排序(Quick Sort) _c++ 」

ice_moss發表於2021-03-23

一、介紹:

快速排序(Quick_sort)是對氣泡排序演算法的一種改進。

快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:透過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序

中文名: 快速排序演算法

外文名: quick sort

別 名: 快速排序

時間複雜度:O(nlogn)

穩定性:穩定

提出者: C. A. R. Hoare

提出時間: 1960年

二、邏輯

1.將數分為兩個部分,假設數中用一值為v,第一部分 < v , 第二部分 > v ;然後將這兩部分進行遞迴呼叫,然後每一部分又分成了子兩部分,再將每一個子部分進行遞迴呼叫,依次遞迴下去,直到每一個元素為止。

2.例如:(文字有點多,請耐心看完,跟著邏輯走)

陣列arr{5, 4, 7, 2, 1, 8},首先我們取一個值作為(二.1)中v;我們也可以使用arr中的任何一個元素(如果取任意數j就需要使用生成隨機數的methods),這裡我們就用第一個元素,即v = 5;

(1) 將v放在一邊從第二個數開始比較此時:arr[1] = 4;

Arr[1] < v,將arr[1]放置陣列左邊(此時已是左邊),然後比較arr[2] = 7;

(2)arr[2] > v, 所以將arr[2]放置右邊(此時遍歷剛開始,後面的元素還未遍歷,此時arr[2]相對於遍歷的元素已經是右邊,arr[2])仍為原來位置),再進行下一個元素的比較 arr[3] = 2;

(3) arr[3] < v,所以需要將arr[3]放置素組的左邊從而得到陣列:

arr{5, 4, 2, 7, 1, 8}

再比較下一個元素 arr[4] = 1;

(4) arr[4] < v,所以需要將arr[4]放置素組的左邊從而得到陣列:

arr{5, 4, 2,1, 7, 8}

再比較下一個元素 arr[5] = 8

(5) arr > v 所以需要將arr[5]放置素組的右邊從而得到陣列:

arr{5, 4, 2,1, 7, 8}

***此時第一步已經完成,接下來將arr{5, 4, 2,1, 7, 8}中,

{arr{ 4, 2,1, 7, 8}進行遞迴,將 > v 和 < v的元素分為兩部分,如下:

Arr1{, 4, 2,1}和arr2{ 7, 8}將兩陣列再進行上述2.(1)~ 2.(5)操作,一直直到遞迴到每一個元素本身為止

最後將每一個v將插入兩”< v”和”> v”之間,就可的到排序完成的陣列

arr{1, 2, 4, 5, 7, 8}

2.(1)~ 2.(5)操作為建構函式為partition

#include <iostream>
using namespace std;

template<typename T> //使用模板函式
int partition(T arr[], int l, int r){
    int v = arr[l];
    int j = l;
    for(int i=j+1; i<=r; i++){
        if(arr[i] < v){
           swap(arr[j+1], arr[i]);
           j++;
        }

}
    swap(arr[l], arr[j]);
    return j;
}

三.程式碼實現

#include <iostream>
using namespace std;

template<typename T>
int partition(T arr[], int l, int r){
    //也可用生成隨機數的方法來取陣列中任意數
    int v = arr[l];
    int j = l;
    for(int i=j+1; i<=r; i++){
        if(arr[i] < v){
          //swap函式來自c++庫
            j++
            swap(arr[j], arr[i]);
        }

    }
    swap(arr[l], arr[j]);
    return j;

}

template<typename T>
void __quicksort(T arr[], int l, int r){
  //遞迴限制條件
    if(l>=r)
        return;

    int p = partition(arr, l , r);
  //遞迴呼叫
    __quicksort(arr, l, p-1);
    __quicksort(arr, p+1, r);

}
//定義函式QuickSort
template<typename T> //使用模板函式
void QuickSort(T arr[], int n){

    __quicksort(arr ,0, n-1);
}

下面做一個簡單測試:

int main() {
    int n;
  //請輸入元素個數
    cin>>n;
    int a[n];
  //這裡我使用指標
    int *p;
    p = a;
    for(int i=0; i<n; i++) {
        cin >> *(p+i);
    }
    QuickSort(p, n);
    for(int i=0; i<n; i++){
        cout<<*(p+i)<<endl;
    }
    return 0;
}

如果不使用指標:

int main() {
    int n;

    cin>>n;
    int a[n];
    for(int i=0; i<n; i++) {
        cin >> a[i];
    }
    QuickSort(a, n);
    for(int i=0; i<n; i++){
        cout<<a[i]<<endl;
    }
    return 0;
}
請輸入元素個數:5
5
4
3
2
1

輸出結果如下:

1
2
3
4
5

Process finished with exit code 0
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章