Fisher-Yates 洗牌演算法

更新 發佈閱讀 5 分鐘

相信你對於演算法有了一點認識,如果今天要求您將一組牌進行洗牌的動作,該怎麼做?

Fisher-Yates 洗牌演算法

Fisher-Yates 洗牌算法是從 最後一個數開始隨機選擇並交換,其用意是為了公平的打亂,使得每種組合的機率相等,且能夠保證 O(N) 的時間複雜度。

O(N)簡單介紹

O(N) 代表 「線性時間(Linear Time)」,表示演算法的執行時間與輸入大小 N 成正比

簡單來說:當 N 增加,執行時間也會以相同比例增加。

  • N = 10,執行大約 10 次
  • N = 100,執行大約 100 次

這邊要特別提醒一點,通常程式步驟的時間複雜度會是用程式執行會碰到的最壞狀況 (Worst Case) 來表示

也因此,當我們要從 n 個櫃子中找到特定的目標,最慘的情況需要花剛好 n 個步驟才能找到,我們就會說此搜尋的時間複雜度為 O(n)

O(N) 與其他複雜度的比較

raw-image

好,回到主題,我們來分析一下程式碼的思維。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 函數生成一組隨機排序的唯一數字
void generateRandomUniqueNumbers(int arr[], int size) {
// 步驟 1:初始化陣列,依序填入從 1 到 size 的數字
for (int i = 0; i < size; i++) {
arr[i] = i + 1; // 將每個元素賦予從 1 到 size 的唯一數值
}

// 步驟 2:使用 Fisher-Yates 演算法將陣列隨機打亂
for (int i = size - 1; i > 0; i--) { // 從陣列尾部開始向前迭代
// 生成一個介於 0 和 i 之間的隨機索引 j
int j = rand() % (i + 1);

// 交換索引 i 和 j 的元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 到此為止,arr 包含了從 1 到 size 的數字並隨機排列
}

int main() {
int n;

// 步驟 1:詢問用戶需要生成的唯一隨機整數數量
printf("Enter the number of unique random integers (excluding 0): ");
scanf("%d", &n);

// 步驟 2:宣告一個陣列來儲存唯一隨機數字
int arr[n];

// 步驟 3:將隨機數生成器的種子設為當前時間
srand(time(0));

// 步驟 4:生成隨機唯一數字
generateRandomUniqueNumbers(arr, n);

// 步驟 5:輸出隨機排序的唯一整數
printf("Random unique integers:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]); // 輸出陣列中的每個數字
}
printf("\n"); // 打印完所有數字後換行

return 0;
}
  • Fisher-Yates 洗牌演算法步驟
    • 從最後一個元素開始,選擇 i = N-1(索引從 4 開始)。
    • [0, i] 區間內選擇一個隨機索引 j,並與 array[i] 交換。
    • 縮小範圍 i--,繼續隨機選取 j,直到 i = 0

步驟示範

初始陣列:

索引:  0   1   2   3   4
數字: [1, 2, 3, 4, 5] // 原始數組

第一輪(i = 4,隨機選擇 j = 2)

  1. i = 4(最後一個元素 5
  2. [0, 4] 中選擇 j = 2
  3. 交換 array[4]array[2]
索引:  0   1   2   3   4
數字: [1, 2, 5, 4, 3]

第二輪(i = 3,隨機選擇 j = 1)

  1. i = 3(元素 4
  2. [0, 3] 中選擇 j = 1
  3. 交換 array[3]array[1]
索引:  0   1   2   3   4
數字: [1, 4, 5, 2, 3]

第三輪(i = 2,隨機選擇 j = 2)

  1. i = 2(元素 5
  2. [0, 2] 中選擇 j = 2
  3. 因為 j = i,不交換
索引:  0   1   2   3   4
數字: [1, 4, 5, 2, 3]
  • (這一步 i = j,所以不變)

第四輪(i = 1,隨機選擇 j = 0)

  1. i = 1(元素 4
  2. [0, 1] 中選擇 j = 0
  3. 交換 array[1]array[0]
索引:  0   1   2   3   4
數字: [4, 1, 5, 2, 3]

完成洗牌!

最終結果(每次執行可能不同):

[4, 1, 5, 2, 3]
留言
avatar-img
留言分享你的想法!
avatar-img
電資鼠 - 您的學習好夥伴
14會員
242內容數
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
2025/03/09
雙向串列 (Double Linked List, DLL) 是一種鏈結資料結構,本章節將以完整註解,搭配關鍵操作地方的圖示輔助學習,讓你輕鬆搞懂複雜觀念,並透過C語言實作。
Thumbnail
2025/03/09
雙向串列 (Double Linked List, DLL) 是一種鏈結資料結構,本章節將以完整註解,搭配關鍵操作地方的圖示輔助學習,讓你輕鬆搞懂複雜觀念,並透過C語言實作。
Thumbnail
2025/03/08
環狀鏈結串列是一種特殊的鏈結串列,其最後一個節點的指標指向第一個節點,而非 NULL,形成一個循環結構。本章節將以豐富圖示,引導讀者了解環狀串列在各種地方執行插入和刪除節點的步驟,輕鬆學會資工科的專業知識-環狀串列。
Thumbnail
2025/03/08
環狀鏈結串列是一種特殊的鏈結串列,其最後一個節點的指標指向第一個節點,而非 NULL,形成一個循環結構。本章節將以豐富圖示,引導讀者了解環狀串列在各種地方執行插入和刪除節點的步驟,輕鬆學會資工科的專業知識-環狀串列。
Thumbnail
2025/03/07
本章節將探討右上三角稀疏矩陣。
Thumbnail
2025/03/07
本章節將探討右上三角稀疏矩陣。
Thumbnail
看更多
你可能也想看
Thumbnail
在小小的租屋房間裡,透過蝦皮購物平臺採購各種黏土、模型、美甲材料等創作素材,打造專屬黏土小宇宙的療癒過程。文中分享多個蝦皮挖寶地圖,並推薦蝦皮分潤計畫。
Thumbnail
在小小的租屋房間裡,透過蝦皮購物平臺採購各種黏土、模型、美甲材料等創作素材,打造專屬黏土小宇宙的療癒過程。文中分享多個蝦皮挖寶地圖,並推薦蝦皮分潤計畫。
Thumbnail
小蝸和小豬因購物習慣不同常起衝突,直到發現蝦皮分潤計畫,讓小豬的購物愛好產生價值,也讓小蝸開始欣賞另一半的興趣。想增加收入或改善伴侶間的購物觀念差異?讓蝦皮分潤計畫成為你們的神隊友吧!
Thumbnail
小蝸和小豬因購物習慣不同常起衝突,直到發現蝦皮分潤計畫,讓小豬的購物愛好產生價值,也讓小蝸開始欣賞另一半的興趣。想增加收入或改善伴侶間的購物觀念差異?讓蝦皮分潤計畫成為你們的神隊友吧!
Thumbnail
高中數學主題練習—配方法
Thumbnail
高中數學主題練習—配方法
Thumbnail
高中數學主題練習—配方法
Thumbnail
高中數學主題練習—配方法
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
我捨棄了編號系統,解放三倍大腦思考能量
Thumbnail
我捨棄了編號系統,解放三倍大腦思考能量
Thumbnail
演算法映射化簡的核心觀念 在面對新題目的時候,除了重頭想一個新的演算法之外; 還有另一個方法,想看看有沒有核心觀念彼此相同的問題與演算法, 如果有,就可以把新的題目映射化簡到已知解法的問題,用已知的演算法去解開。 接著,我們會介紹幾個範例,並且使用映射化簡的技巧來解題,透過化
Thumbnail
演算法映射化簡的核心觀念 在面對新題目的時候,除了重頭想一個新的演算法之外; 還有另一個方法,想看看有沒有核心觀念彼此相同的問題與演算法, 如果有,就可以把新的題目映射化簡到已知解法的問題,用已知的演算法去解開。 接著,我們會介紹幾個範例,並且使用映射化簡的技巧來解題,透過化
Thumbnail
解決電腦上遇到的問題、證明正確性、探討效率 並且很著重溝通,說服別人你做的事是正確且有效率的。 內容: 計算模型、資料結構介紹、演算法介紹、時間複雜度介紹。
Thumbnail
解決電腦上遇到的問題、證明正確性、探討效率 並且很著重溝通,說服別人你做的事是正確且有效率的。 內容: 計算模型、資料結構介紹、演算法介紹、時間複雜度介紹。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News