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) 與其他複雜度的比較

vocus|新世代的創作平台

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

#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
電資鼠 - 您的學習好夥伴
25會員
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
若說易卜生的《玩偶之家》為 19 世紀的女性,開啟了一扇離家的窄門,那麼《海妲.蓋柏樂》展現的便是門後的窒息世界。本篇文章由劇場演員 Amily 執筆,同為熟稔文本的演員,亦是深刻體察制度縫隙的當代女性,此文所看見的不僅僅是崩壞前夕的最後發聲,更是女人被迫置於冷酷的制度之下,步步陷入無以言說的困境。
Thumbnail
若說易卜生的《玩偶之家》為 19 世紀的女性,開啟了一扇離家的窄門,那麼《海妲.蓋柏樂》展現的便是門後的窒息世界。本篇文章由劇場演員 Amily 執筆,同為熟稔文本的演員,亦是深刻體察制度縫隙的當代女性,此文所看見的不僅僅是崩壞前夕的最後發聲,更是女人被迫置於冷酷的制度之下,步步陷入無以言說的困境。
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
我捨棄了編號系統,解放三倍大腦思考能量
Thumbnail
我捨棄了編號系統,解放三倍大腦思考能量
Thumbnail
本文深度解析賽勒布倫尼科夫的舞臺作品《傳奇:帕拉贊諾夫的十段殘篇》,如何以十段殘篇,結合帕拉贊諾夫的電影美學、象徵意象與當代政治流亡抗爭,探討藝術在儀式消失的現代社會如何承接意義,並展現不羈的自由靈魂。
Thumbnail
本文深度解析賽勒布倫尼科夫的舞臺作品《傳奇:帕拉贊諾夫的十段殘篇》,如何以十段殘篇,結合帕拉贊諾夫的電影美學、象徵意象與當代政治流亡抗爭,探討藝術在儀式消失的現代社會如何承接意義,並展現不羈的自由靈魂。
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
中學數學基礎練習—一元一次方程式
Thumbnail
長期以來,西方美學以《維特魯威人》式的幾何比例定義「完美身體」,這種視覺標準無形中成為殖民擴張與種族分類的暴力工具。本文透過分析奈及利亞編舞家庫德斯.奧尼奎庫的舞作《轉轉生》,探討當代非洲舞蹈如何跳脫「標本式」的文化觀看。
Thumbnail
長期以來,西方美學以《維特魯威人》式的幾何比例定義「完美身體」,這種視覺標準無形中成為殖民擴張與種族分類的暴力工具。本文透過分析奈及利亞編舞家庫德斯.奧尼奎庫的舞作《轉轉生》,探討當代非洲舞蹈如何跳脫「標本式」的文化觀看。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News