雙緩衝陣列 cur[R][C], nxt[R][C]。每輪對每個細胞計算 8 鄰居存活數,應用規則寫入 nxt,再交換指標。時間 O(R×C),與活細胞數無關。
只有狀態發生變化的細胞(出生/死亡)會影響下一輪鄰居的鄰居計數。死寂區域無需重複計算。
typedef struct {
char live; // 當前狀態 0/1
char nbr_old; // 上一輪鄰居數(決策依據)
char nbr_new; // 本輪累積鄰居數(受本輪變化影響)
char changed; // 本輪是否狀態翻轉
} Cell;
nbr_old++。nbr_old 依規則決定新狀態 → 設 changed。changed:翻轉 live,對 8 鄰居 nbr_new += (new_live ? +1 : -1)。nbr_old = nbr_new; nbr_new = 0; changed = 0(或交換指標)。void process_cell(World *w, int r, int c) {
Cell *cell = &w->grid[r][c];
int live = cell->live;
int nbr = cell->nbr_old;
int new_live = (live && (nbr==2 || nbr==3)) || (!live && nbr==3);
if (new_live != live) {
cell->changed = 1;
int delta = new_live ? +1 : -1;
cell->live = new_live;
w->live_cnt += delta;
notify_neighbors(w, r, c, delta); // 更新鄰居 nbr_new
}
}
void notify_neighbors(World *w, int r, int c, int delta) {
for (int dr=-1; dr<=1; ++dr)
for (int dc=-1; dc<=1; ++dc)
if (dr||dc) w->grid[r+dr][c+dc].nbr_new += delta;
}
| 演算法 | 時間/輪 | 空間 | 適用場景 |
|---|---|---|---|
| 全盤掃描 | O(R×C) | O(R×C) | 小網格、密集活細胞 |
| 主動通知 | O(變化細胞數 × 8) | O(R×C) + 額外欄位 | 大稀疏網格、長期演化 |
僅維護「活細胞」與「鄰近活細胞的死細胞」集合(哈希表/平衡樹),完全跳過死寂區域遍歷,實現真正 O(活躍區域)。適合無限網格或極大稀疏場景(如 Golly 模擬器核心思路)。
nbr_old/nbr_new、live/changed 中雙重體現。