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的优势在于只需要记录被删除的结构元素就可以轻易的回复的前一个状态。对于下图矩阵

dancing links - 舞蹈的链表_第1张图片

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

dancing links - 舞蹈的链表_第2张图片

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

dancing links - 舞蹈的链表_第3张图片

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

dancing links - 舞蹈的链表_第4张图片

 

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

 

 

你可能感兴趣的:(优化)