用Dancing Links解决数独(Sudoku)问题

Dancing Links可以认为是一种数据结构(好像本校面向大二年级开设的数据结构课程中就有它),其实就是一种链表,准确地讲是十字双向循环链表

十字:普通链表是一条线,而十字链表就是一张网,每个结点不仅有左右邻居,还有上下邻居。
双向:双向是链表中很经典的概念,即每个结点要保存上下左右四个方向的邻居指针。
循环:循环也是比较常见的概念了,即每一行的最左结点的左邻居设置为这一行的最右结点,最右结点的右邻居设置为最左结点;每一列同理。

至此,Dancing Links的基本样子就有了。对于有一点点数据结构基础的同学来说(比如我),十字双向循环链表可能比一整页的详细描述更好懂吧……
不难看出,这个数据结构很像是矩阵,很适合用来维护稀疏矩阵的元素。
不过,Dancing Links一般还含有两种特殊类型的结点——头结点(Head)和列结点(Column)。
如果我们把矩阵元素坐标用\((1...n,1...m)\)来表示,那么头结点就是\((0,0)\),列结点就是\((0,1...m)\)
头结点可以看为是我们访问所有结点的一个入口,额外创建一个这样的头结点是因为我们在后续过程中始终不会将该结点移除,不像其他结点可能被删掉(那样我们用那个结点就不一定能找到当前剩余的全部元素了)。
列结点私以为是用来辅助Dancing Links X算法的(一个用来解决Exact Cover问题的算法)。

来自HatenaBlog

Exact Cover 问题

设全集是\(S\),给出一些子集\(S_i\),要求选一些子集出来,恰好包含\(S\)的所有元素且每个元素只被一个子集包含。

算法描述

首先用01矩阵\(A\)描述上面的问题。
每一行代表一个子集,每一列代表一个元素。
比如子集\(S_i\)包含元素\(a_j\),那么\(A_{i,j}=1\);如果子集\(S_i\)不包含元素\(a_j\),那么\(A_{

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值