dancing links - 舞蹈的链表

 

 

  看了Donald E. Knuth关于dancing links的原文后,不得不说文章中处处透漏着艺术气息,Knuth不亏是一代大师。

  本文不能算是深入的总结,或者说连翻译也算不上,权当是学习dancing links的笔记。

  首先解释一下什么是dancing links

  对于双向链表,假设x是双向链表的一个元素,L(X)指向x元素的前一个元素,R(X)指向x元素的后一个元素,那么删除元素X操作为:L(R(X)) = L(X) R(L(X)) = R(X) ,大部分情况下删除元素后都会将所涉及的所有指针置空。那么我们再看看如果恢复X在链表中的位置: L(R(X)) =  X R(L(X)) = X.(如下图回溯,X元素的只是被间接隐藏起来,降低了回溯的成本) 这两个操作看起来是不是简单明了易于理解,但如作者所说,很多时候是不需要这么做的,这样做有可能会导致野指针泛滥,会有不可预知的错误。但是这个简单的操作却可以很容易的带来程序设计中的便利,比如很多时候需要处理回溯这个操作的时候,这个结构却非常的高效,回溯的过程中,只需要知道x就就可以进行撤销这个操作了。引用作者的原话:“这个过程就像是全局结构下的指针变量做着精心设计的舞蹈,所以我称这个技术为dancing links"

  dlx主要用于完整覆盖问题,回溯过程中的undo操作,返回前一个状态有很多种实现方式,但dlx的优势在于只需要记录被删除的结构元素就可以轻易的回复的前一个状态。对于下图矩阵

可使用下图的链表进行表示

回溯过程如下图(回溯的精髓主要在减枝,如果dlx主要应用在特殊领域的优化)

DLX可以解决的覆盖问题如下图

 

如果想深入了解,参见knuth关于Dancing links的论文

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值