Sorting Algorithms

by 洪翠憶

快樂影片:D

快樂遊戲:D

Selection Sort

幫每個位置,選擇該放的值。

– 選擇排序法

選擇排序法

選擇排序法

選擇排序法

選擇排序法

選擇排序法

選擇排序法

選擇排序法

  • 從尚未分類的值堆中,找出最小(最大)的,依序放下去,直到所有元素都排完
  • 時間複雜度:O(n²)

選擇排序法

試著寫出選擇排序法吧~

選擇排序法

int arr[10] = {3, 5, 2, 7, 1, 4, 6, 8, 9, 0};

void selection_sort(){
    for(int i = 0; i < 10; i++){
        int mini = arr[i], point = i;
        for(int j = i; j < 10; j++){
            if(arr[j] < mini){
                mini = arr[j];
                point = j;
            }
        }
        std::swap(arr[i], arr[point]);
    }
}

Bubble Sort

泡沫那樣,大顆的泡泡會先浮上去。

– 泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

泡沫排序法

  • 重複檢查兩相鄰元素是否有依序,直到全部排序完成。
  • 時間複雜度:O(n²)

泡沫排序法

試著寫出泡沫排序法吧~

泡沫排序法

int arr[10] = {3, 5, 2, 7, 1, 4, 6, 8, 9, 0};

void selection_sort(){
    for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9-i; j++){
            if(arr[j] > arr[j+1]){
                std::swap(arr[j], arr[j+1]);
            }
        }
    }
}

Insertion Sort

從第二個數字開始,幫每個值插入正確的位置。

– 插入排序法

插入排序法

插入排序法

插入排序法

插入排序法

插入排序法

插入排序法

  • 選取未分類的值,在已分類區中由後往前掃描合適的位置,然後放入。
  • 時間複雜度:O(n²)

插入排序法

試著寫出插入排序法吧~

插入排序法

int arr[10] = {3, 5, 2, 7, 1, 4, 6, 8, 9, 0};

void insertion_sort(){
    for(int i = 1; i < 9; i++){
        int ins = arr[i], j = i-1;
        while(j >= 0 && arr[j] > ins){
            std::swap(arr[j], arr[j+1]);
            j--;
        }
        arr[j+1] = ins;
    }
}

Introsort(std::sort)

  • 先從快速排序開始,當遞迴深度超過一定深度(深度為排序元素數量的對數值)後轉為堆積排序。
  • 時間複雜度:O(n‧log(n))

內省排序法

(有興趣深入了解的話,可以自己上網查www)

std::sort()

#include <algorithm>
⋮
std::sort(迭代器的頭, 迭代器的尾, 排序規則(選填));

語法:

std::sort()

#include <algorithm>
#include <iostream>

int arr[10] = {3, 5, 2, 7, 1, 4, 6, 8, 9, 0};

int main(){
    for(int i = 0; i < 10; i++)  //輸出原本的排序
        std::cout << arr[i] << ' ';
    std::cout << '\n';
    std::sort(arr, arr+10);  //排序
    for(int i = 0; i < 10; i++)//輸出排序好的排序
        std::cout << arr[i] << ' ';
    return 0;
}

std::sort() 有排序規則的舉例

#include <algorithm>
#include <iostream>

int arr[10] = {3, 5, 2, 7, 1, 4, 6, 8, 9, 0};

bool mycomp(int a, int b){
    return a > b;
}

int main(){
    for(int i = 0; i < 10; i++)  //輸出原本的排序
        std::cout << arr[i] << ' ';
    std::cout << '\n';
    std::sort(arr, arr+10, mycomp);  //由大到小排序
    for(int i = 0; i < 10; i++)//輸出排序好的排序
        std::cout << arr[i] << ' ';
    return 0;
}

Merge Sort

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

合併排序法

  • 先遞迴把當前序列平均分割成兩半,直到每項序列都只剩下兩個元素,此時分別排序兩個元素,再與相鄰且大小相同的另一序列依序比對最小值進行排序,合併出稍大的序列,就這樣重複遞迴地合併直到結束。
  • 分治法典型應用
  • 時間複雜度:O(n‧log(n))

合併排序法

合併排序法

int arr[10] = {3, 5, 2, 7, 1, 4, 6, 8, 9, 0};

void merge_sort(int a[], int be, int en){
    if(be + 1 >= en)
        return;
    int mid = (be + en) / 2;
    merge_sort(a, be, mid);
    merge_sort(a, mid, en);
    int wait[en-be], j = mid, k = 0;
    for(int i = be; i < mid; i++){
        while(j < en && a[j] < a[i]){
            wait[k++] = a[j++];
        }
        wait[k++] = a[i];
    }
    for(k = be; k < j; k++){
        a[k] = wait[k-be];
    }
    return;
}

Binary Search

二分搜尋法

想找

二分搜尋法

二分搜尋法

二分搜尋法

二分搜尋法

二分搜尋法

找到了!

  • 在已排序的序列中從中間切,若沒找到,且目前的值比要找的值大,則往值較小的方向找,反之亦然。
  • 時間複雜度:O(log(n))

二分搜尋法

二分搜尋法(迴圈版本)

#include <iostream>

int arr[10] = {4, 5, 7, 13, 23, 27, 30, 31, 36, 38};

int bi_search(int a){
    int s = 0, e = 9, i;
    do{
        i = (e + s) / 2;
        if(arr[i] == a){
            return i;
        }else if(arr[i] > a)
            e = i;
        else
            s = i;
    }while(e - s > 0);
}

int main(){
    std::cout << "find it at " << bi_search(36) << ".\n";
    return 0;
}

遞迴版的當加分題~

std::binary_search()

#include <algorithm>
#include <iostream>

int arr[10] = {4, 5, 7, 13, 23, 27, 30, 31, 36, 38};

int main(){
    if(std::binary_search(arr, arr+10, 36)){
        std::cout << "Found it.\n";
    }
    return 0;
}

語法:

#include <algorithm>
⋮
std::binary_search(迭代器的頭, 迭代器的尾, 要搜尋的值, 排序規則(選填));

Kahoot!

References

Made with Slides.com