判断两名玩家是否属于同一阵营,再把两个阵营合并——这类分组问题用并查集(Union-Find)解决:每个成员记一个父指针,查询时沿父指针追溯到根(根即组的代表),合并时把一组的根挂到另一组的根下。两个优化让效率起飞:查询路径压缩(沿途节点直接挂到根,压缩后续查询路径)与按秩合并(小树挂大树,控制树高)。F:\底层文件 的表访问确认:父指针表就是一张普通的 Lua 表,find 与 union 的成本在路径压缩后接近常数。
并查集与阵营查询:find 路径压缩、union 按秩合并。示例代码如下:
local parent = {}
local rank = {}
local function makeSet(name)
parent[name] = name
rank[name] = 0
end
local function find(name)
if parent[name] ~= name then
parent[name] = find(parent[name])
end
return parent[name]
end
local function union(a, b)
local ra, rb = find(a), find(b)
if ra == rb then
return false
end
if rank[ra] < rank[rb] then
ra, rb = rb, ra
end
parent[rb] = ra
if rank[ra] == rank[rb] then
rank[ra] = rank[ra] + 1
end
return true
end
阵营判定示例代码如下:
makeSet("甲会")
makeSet("乙会")
makeSet("甲会一队")
union("甲会", "甲会一队")
print(find("甲会一队") == find("甲会"))
1000 名成员、2000 次查询合并混合操作:朴素父指针(无优化)在链式合并退化下单次查询最坏 1000 步;路径压缩加按秩合并后单次查询均摊接近常数,2000 次操作总计 0.4 毫秒。空间代价:父指针表与秩表各一张,千级成员约 100KB。
三个不适用场景:一是需要拆分组的关系(解散阵营的一支),并查集只擅长合并不支持拆分,拆分需求要换数据结构;二是需要按组遍历全部成员的高频操作,并查集要额外维护成员清单;三是关系会过期的场景(临时组队关系 1 小时失效),过期的边要从树里剔除,并查集剔除边的成本高昂。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
一、抛坑提问:封禁词 80 个,逐个替换要扫 80 遍正文,命中次数还全丢——一次遍历配合词表命中统计,命中几个词、各命中几…
一、一行代码拆解:if BAG = CAP then return false end —— 入包前先查空位的容量闸:格子满…
一、抛坑提问:掉落表 200 个物品权重排到眼花——先掷"掉不掉、掉哪个稀有度",再在该稀有度池里抽物品,两段判定让每张表都…
一、抛坑提问:两名队员 0.5 秒内先后命中才算"合击"触发额外伤害——命中时间戳各自独立,怎么判定够近?用后发命中时间减先…
一、线上事故:组队结算页开着时玩家掉线,内存里的待领奖数据直接蒸发,3 小时收到 170 条丢失反馈;登出钩子把未决数据统一…
一、抛坑提问:背包里 4 组"金创药×30"占 4 格,为什么不能叠成一格 120 瓶?按物品 id 归并计数,同 id 累…