<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>



<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document"><title>backtrack by doubly-link</title>

<style>
<!--
table.MsoTableGrid
	{border:1.0pt solid windowtext;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.0pt;
	font-family:"Times New Roman";
	}
 li.MsoNormal
	{mso-style-parent:"";
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:"Times New Roman";
	margin-left:0cm; margin-right:0cm; margin-top:0cm}
-->
</style></head><body rightmargin="1" bottommargin="1" marginheight="1" marginwidth="1">



<p align="left"><span lang="en-ca"><font color="#ff0000" size="6"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Dancing Link</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. <span lang="en-ca">First </span>Edition</font></b></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>This is a program to implement the so-called "dancing link" which is introduced in Knuth's paper. This is really a super</b></span></pre>
</div>
<div align="left">
	<pre><span lang="en-ca"><b>acrobatic and I am sure that not many programmers can understand the algorithms. </b></span></pre>
</div>
<div align="left">
	<pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <span lang="en-ca">The exact cover problem:</span></div>
<div align="left">
  　</div>
<div align="left">
  {0,0,1,0,1,1,0},<br>
	{1,0,0,1,0,0,1},<br>
	{0,1,1,0,0,1,0},<br>
	{1,0,0,1,0,0,0},<br>
	{0,1,0,0,0,0,1},<br>
	{0,0,0,1,1,0,1}</div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca">As for the above matrix, can you find a subset of rows such 
	that each column has exactly one 1. Can you find such a subset</span></div>
<div align="left">
  <span lang="en-ca">of rows? This is a typical NP-complete problem.</span></div>
<div align="left">
  　</div>
<div align="left">
  　</div>
<div align="left">
  　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font color="#ff0000" size="5"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<p><span lang="en-ca">In order to understand the total idea, you have to refer 
Knuth's <a href="http://www-cs-faculty.stanford.edu/%7Eknuth/preprints.html">paper 
here.</a> </span></p>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
	<pre>　</pre>
</div>
<div align="left">
	<pre><span lang="en-ca">I lost patience of explaining the complicated algorithms because I don't understand it quite well myself.</span></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font color="#ff0000" size="5"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font color="#ff0000" size="5"><b>File listing</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div><br>
1. dancingLink.cpp<br>
<br>
　<br>
<br>
file name: dancingLink.cpp<br>
<br>
#include &lt;iostream&gt;<br>
<br>
using namespace std;<br>
<br>
enum Direction<br>
{<br>
&nbsp;&nbsp;&nbsp; Left, Right, Up, Down<br>
};<br>
<br>
const int RowNumber=6;<br>
const int ColNumber=7;<br>
const int MaxNameLength=32;<br>
const int MaxDataLength=32;<br>
const int MaxBackTrackDepth=RowNumber;<br>
<br>
struct Node<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* L;<br>
&nbsp;&nbsp;&nbsp; Node* R;<br>
&nbsp;&nbsp;&nbsp; Node* U;<br>
&nbsp;&nbsp;&nbsp; Node* D;<br>
&nbsp;&nbsp;&nbsp; Node* C;<br>
&nbsp;&nbsp;&nbsp; char* data;<br>
&nbsp;&nbsp;&nbsp; int size;<br>
&nbsp;&nbsp;&nbsp; char* name;<br>
&nbsp;&nbsp;&nbsp; void display()<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (name!=NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;"name="&lt;&lt;name&lt;&lt;"\n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (data!=NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;"data="&lt;&lt;data&lt;&lt;"\n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (size!=-1)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;"size="&lt;&lt;size&lt;&lt;"\n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
};<br>
<br>
Node* stack[MaxBackTrackDepth];<br>
<br>
<br>
int matrix[RowNumber][ColNumber]=<br>
{<br>
&nbsp;&nbsp;&nbsp; {0,0,1,0,1,1,0},<br>
&nbsp;&nbsp;&nbsp; {1,0,0,1,0,0,1},<br>
&nbsp;&nbsp;&nbsp; {0,1,1,0,0,1,0},<br>
&nbsp;&nbsp;&nbsp; {1,0,0,1,0,0,0},<br>
&nbsp;&nbsp;&nbsp; {0,1,0,0,0,0,1},<br>
&nbsp;&nbsp;&nbsp; {0,0,0,1,1,0,1}<br>
};<br>
<br>
Node* nodeStep(Node* node, Direction dir, int step);<br>
void rightInsert(Node* theLeft, Node* theNode);<br>
void downInsert(Node* theUpper, Node* theNode);<br>
void horizonRemove(Node* node);<br>
void verticalRemove(Node* node);<br>
Node* createNode();<br>
void display(Node* head);<br>
Node* initialize(int** matrix);<br>
Node* createHeader(int colNumber);<br>
//I prefer to make the pointer null which is safe<br>
void uninitialize(Node*&amp; head);<br>
<br>
void printSolution(int depth);<br>
void search(Node* head, int depth);<br>
<br>
<br>
<br>
<br>
<br>
Node* initialize(int matrix[][ColNumber])<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* result=createHeader(ColNumber);<br>
&nbsp;&nbsp;&nbsp; Node* start=result-&gt;R;<br>
&nbsp;&nbsp;&nbsp; Node* upper, *left, *node, *currentHeader;<br>
<br>
&nbsp;&nbsp;&nbsp; for (int r=0; r&lt;RowNumber; r++)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; left=NULL;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (int c=0; c&lt;ColNumber; c++)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (matrix[r][c]&gt;0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //create a new node<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //when the node is created, it is self-circule<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //which means it loop both l,r,u,d by itself, <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; //so it is safe to just insert either horizontal or
verticle<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node=createNode();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;data=new char[MaxDataLength];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; sprintf(node-&gt;data, "data row[%d],col[%d]", r, c);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //get current header node<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; currentHeader=nodeStep(start, Right, c);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (currentHeader-&gt;size==0)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; upper=currentHeader;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //move downwards to the current
upper of inserted node<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; upper=nodeStep(currentHeader,
Down, currentHeader-&gt;size);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //insert node and update header<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; downInsert(upper, node);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;C=currentHeader;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; currentHeader-&gt;size++;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //possible to insert into row link<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (left!=NULL)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rightInsert(left,
node);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //this is done always<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; left=node;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
Node* nodeByDirection(Node* node, Direction dir)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* result=NULL;<br>
&nbsp;&nbsp;&nbsp; switch (dir)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; case Left:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result= node-&gt;L;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; case Right:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result= node-&gt;R;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; case Down:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result=node-&gt;D;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; case Up:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result=node-&gt;U;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
void doDisplay(Node* node, Direction dir)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* ptr=node;<br>
&nbsp;&nbsp;&nbsp; while (true)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=nodeByDirection(ptr, dir);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (ptr==node)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr-&gt;display();<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
void display(Node* head)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* node=head-&gt;R;<br>
&nbsp;&nbsp;&nbsp; //cout&lt;&lt;"now display header rows\n";<br>
&nbsp;&nbsp;&nbsp; //doDisplay(head, Right);<br>
&nbsp;&nbsp;&nbsp; cout&lt;&lt;"************************now display column by column**********************\n";<br>
&nbsp;&nbsp;&nbsp; while (node!=head)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //node=nodeStep(head, Right, i);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;"&gt;&gt;&gt;now display column&lt;&lt;&lt;\n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;display();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; doDisplay(node, Down);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node=node-&gt;R;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
<br>
Node* createHeader(int colNumber)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* result=createNode();<br>
&nbsp;&nbsp;&nbsp; Node* current=result;<br>
&nbsp;&nbsp;&nbsp; Node* node;<br>
&nbsp;&nbsp;&nbsp; result-&gt;name=new char[MaxNameLength];<br>
&nbsp;&nbsp;&nbsp; sprintf(result-&gt;name, "head node with %d column", colNumber); <br>
&nbsp;&nbsp;&nbsp; for (int c=0; c&lt;colNumber; c++)<br>
&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node=createNode();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;size=0;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; node-&gt;name=new char[MaxNameLength];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sprintf(node-&gt;name, "column %d header", c);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rightInsert(current, node);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; current=node;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
Node* nodeStep(Node* node, Direction dir, int step)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* result=node;<br>
&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;step; i++)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result=nodeByDirection(result, dir);<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
<br>
Node* createNode()<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* result;<br>
&nbsp;&nbsp;&nbsp; result=new Node;<br>
&nbsp;&nbsp;&nbsp; result-&gt;L=result;<br>
&nbsp;&nbsp;&nbsp; result-&gt;R=result;<br>
&nbsp;&nbsp;&nbsp; result-&gt;U=result;<br>
&nbsp;&nbsp;&nbsp; result-&gt;D=result;<br>
&nbsp;&nbsp;&nbsp; result-&gt;C=result;<br>
&nbsp;&nbsp;&nbsp; result-&gt;data=NULL;<br>
&nbsp;&nbsp;&nbsp; result-&gt;size=-1;<br>
&nbsp;&nbsp;&nbsp; result-&gt;name=NULL;<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
Node* createNode(char* theData)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* result=createNode();<br>
&nbsp;&nbsp;&nbsp; result-&gt;data=new char[MaxDataLength];<br>
&nbsp;&nbsp;&nbsp; strcpy(result-&gt;data, theData);<br>
&nbsp;&nbsp;&nbsp; return result;<br>
}<br>
<br>
void horizonInsert(Node* node)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* left=node-&gt;L;<br>
&nbsp;&nbsp;&nbsp; Node* right=node-&gt;R;<br>
&nbsp;&nbsp;&nbsp; left-&gt;R=node;<br>
&nbsp;&nbsp;&nbsp; right-&gt;L=node;<br>
}<br>
<br>
void verticalInsert(Node* node)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* upper=node-&gt;U;<br>
&nbsp;&nbsp;&nbsp; Node* lower=node-&gt;D;<br>
&nbsp;&nbsp;&nbsp; upper-&gt;D=node;<br>
&nbsp;&nbsp;&nbsp; lower-&gt;U=node;<br>
}<br>
<br>
void horizonRemove(Node* node)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* left=node-&gt;L;<br>
&nbsp;&nbsp;&nbsp; Node* right=node-&gt;R;<br>
&nbsp;&nbsp;&nbsp; left-&gt;R=right;<br>
&nbsp;&nbsp;&nbsp; right-&gt;L=left;<br>
}<br>
<br>
void verticalRemove(Node* node)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* upper=node-&gt;U;<br>
&nbsp;&nbsp;&nbsp; Node* lower=node-&gt;D;<br>
&nbsp;&nbsp;&nbsp; upper-&gt;D=lower;<br>
&nbsp;&nbsp;&nbsp; lower-&gt;U=upper;<br>
}<br>
<br>
<br>
<br>
//these kind of operation was written to be as simple as possible<br>
//so that even a fool can understand what is going on<br>
void rightInsert(Node* theLeft, Node* theNode)<br>
{<br>
&nbsp;&nbsp;&nbsp; //using temp variable is safer, and you don't have to worry about the<br>
&nbsp;&nbsp;&nbsp; //the order of operation<br>
&nbsp;&nbsp;&nbsp; Node* theRight=theLeft-&gt;R;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;L=theLeft;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;R=theRight;<br>
&nbsp;&nbsp;&nbsp; theLeft-&gt;R=theNode;//danger! if you don't use temp variable<br>
&nbsp;&nbsp;&nbsp; theRight-&gt;L=theNode;<br>
}<br>
<br>
<br>
//these kind of operation was written to be as simple as possible<br>
//so that even a fool can understand what is going on<br>
void downInsert(Node* theUpper, Node* theNode)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* theLower=theUpper-&gt;D;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;U=theUpper;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;D=theLower;<br>
&nbsp;&nbsp;&nbsp; theUpper-&gt;D=theNode;//this order is only true when temp variable is used<br>
&nbsp;&nbsp;&nbsp; theLower-&gt;U=theNode;<br>
}<br>
<br>
void deleteNode(Node* node)<br>
{<br>
&nbsp;&nbsp;&nbsp; if (node-&gt;data!=NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delete node-&gt;data;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; if (node-&gt;name!=NULL)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delete node-&gt;name;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; delete node;<br>
}<br>
<br>
//I prefer to make the pointer null which is safe<br>
void uninitialize(Node*&amp; head)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* right;<br>
&nbsp;&nbsp;&nbsp; Node* lower;<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; right=head-&gt;R;<br>
<br>
&nbsp;&nbsp;&nbsp; while (right!=head)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //now we start to delete this column<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lower=right-&gt;D;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (right!=lower)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //unlink<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; verticalRemove(lower);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //delete<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; deleteNode(lower);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //point to next<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lower=right-&gt;D;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //now we remove header and delete it<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //unlink<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; horizonRemove(right);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //delete<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; deleteNode(right);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //point to next<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; right=head-&gt;R;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; //need to delete head<br>
&nbsp;&nbsp;&nbsp; deleteNode(head);<br>
&nbsp;&nbsp;&nbsp; head=NULL;<br>
}<br>
<br>
Node* nextColumn(Node* head)<br>
{<br>
&nbsp;&nbsp;&nbsp; return head-&gt;R;<br>
}<br>
<br>
void coverColumn(Node* colHeader)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* lower;<br>
&nbsp;&nbsp;&nbsp; Node* right;<br>
&nbsp;&nbsp;&nbsp; //first remove the column header<br>
&nbsp;&nbsp;&nbsp; horizonRemove(colHeader);<br>
&nbsp;&nbsp;&nbsp; lower=colHeader-&gt;D;<br>
&nbsp;&nbsp;&nbsp; while (lower!=colHeader)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; right=lower-&gt;R;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //but we don't unlink ourselves<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (right!=lower)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //unlink data from its column<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; verticalRemove(right);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //reduce size of that column<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; right-&gt;C-&gt;size--;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //go right for next available column<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; right=right-&gt;R;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //go down for next available row<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lower=lower-&gt;D;<br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
void uncoverColumn(Node* colHeader)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* upper;<br>
&nbsp;&nbsp;&nbsp; Node* left;<br>
&nbsp;&nbsp;&nbsp; upper=colHeader-&gt;U;<br>
&nbsp;&nbsp;&nbsp; while (upper!=colHeader)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; left=upper-&gt;L;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (left!=upper)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; verticalInsert(left);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //update the size of column i<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; left-&gt;C-&gt;size++;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; left=left-&gt;L;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; upper=upper-&gt;U;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; horizonInsert(colHeader);<br>
}<br>
<br>
<br>
<br>
void printSolution(int depth)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* ptr;<br>
&nbsp;&nbsp;&nbsp; cout&lt;&lt;"one solution is found\n";<br>
&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;depth; i++)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=stack[i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; do<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;ptr-&gt;C-&gt;name&lt;&lt;"\t";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=ptr-&gt;R;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (ptr!=stack[i]);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cout&lt;&lt;"\n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; }<br>
}<br>
<br>
void search(Node* head, int depth)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* columnHeader;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; Node* row;<br>
&nbsp;&nbsp;&nbsp; Node* ptr;<br>
<br>
&nbsp;&nbsp;&nbsp; if (head==head-&gt;R)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printSolution(depth);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; columnHeader=nextColumn(head);<br>
<br>
&nbsp;&nbsp;&nbsp; //cout&lt;&lt;"********before cover column \n";<br>
&nbsp;&nbsp;&nbsp; //columnHeader-&gt;display();<br>
&nbsp;&nbsp;&nbsp; //display(head);<br>
&nbsp;&nbsp;&nbsp; coverColumn(columnHeader);<br>
&nbsp;&nbsp;&nbsp; //cout&lt;&lt;"********after cover column \n";<br>
&nbsp;&nbsp;&nbsp; //columnHeader-&gt;display();<br>
&nbsp;&nbsp;&nbsp; //display(head);<br>
<br>
&nbsp;&nbsp;&nbsp; row=columnHeader-&gt;D;<br>
<br>
&nbsp;&nbsp;&nbsp; while (row!=columnHeader)<br>
&nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //first we need to leave a trace for us to back track in this <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //stack-like array for data we searched<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stack[depth]=row;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //traverse all column in this row<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=row-&gt;R;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (row!=ptr)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //cout&lt;&lt;"********before cover column \n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //ptr-&gt;C-&gt;display();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //display(head);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; coverColumn(ptr-&gt;C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //cout&lt;&lt;"********after cover column&nbsp; \n";<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //ptr-&gt;C-&gt;display();<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //display(head);<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=ptr-&gt;R;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; search(head, depth+1);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //backtrack<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; row=stack[depth];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; columnHeader=row-&gt;C;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=row-&gt;L;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while (row!=ptr)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; uncoverColumn(ptr-&gt;C);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ptr=ptr-&gt;L;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; row=row-&gt;D;<br>
&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; uncoverColumn(columnHeader);<br>
}<br>
<br>
<br>
int main()<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* head;<br>
&nbsp;&nbsp;&nbsp; head=initialize(matrix);<br>
&nbsp;&nbsp;&nbsp; display(head);<br>
<br>
&nbsp;&nbsp;&nbsp; cout&lt;&lt;"\nnow let's search:\n";<br>
&nbsp;&nbsp;&nbsp; search(head, 0);<br>
&nbsp;&nbsp;&nbsp; uninitialize(head);<br>
&nbsp;&nbsp;&nbsp; <br>
<br>
<br>
<br>
&nbsp;&nbsp;&nbsp; return 0;<br>
}<br>
<br>
<br>
//these kind of operation was written to be as simple as possible<br>
//so that even a fool can understand what is going on<br>
void upInsert(Node* theLower, Node* theNode)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* theUpper=theLower-&gt;U;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;U=theUpper;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;D=theLower;<br>
&nbsp;&nbsp;&nbsp; theUpper-&gt;D=theNode;<br>
&nbsp;&nbsp;&nbsp; theLower-&gt;U=theNode;<br>
}<br>
<br>
//these kind of operation was written to be as simple as possible<br>
//so that even a fool can understand what is going on<br>
void leftInsert(Node* theRight, Node* theNode)<br>
{<br>
&nbsp;&nbsp;&nbsp; Node* theLeft=theRight-&gt;L;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;L=theLeft;<br>
&nbsp;&nbsp;&nbsp; theNode-&gt;R=theRight;<br>
&nbsp;&nbsp;&nbsp; theLeft-&gt;R=theNode;<br>
&nbsp;&nbsp;&nbsp; theRight-&gt;L=theNode;<br>
}<br>
<br>
<br>
　<br>
<br>
A snapshot of running automated testing:<br>
<br>
<br>
<pre>************************now display column by column**********************<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 0 header<br>size=2<br>data=data row[1],col[0]<br>data=data row[3],col[0]<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 1 header<br>size=2<br>data=data row[2],col[1]<br>data=data row[4],col[1]<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 2 header<br>size=2<br>data=data row[0],col[2]<br>data=data row[2],col[2]<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 3 header<br>size=3<br>data=data row[1],col[3]<br>data=data row[3],col[3]<br>data=data row[5],col[3]<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 4 header<br>size=2<br>data=data row[0],col[4]<br>data=data row[5],col[4]<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 5 header<br>size=2<br>data=data row[0],col[5]<br>data=data row[2],col[5]<br>&gt;&gt;&gt;now display column&lt;&lt;&lt;<br>name=column 6 header<br>size=3<br>data=data row[1],col[6]<br>data=data row[4],col[6]<br>data=data row[5],col[6]<br><br>now let's search:<br>one solution is found<br>column 0 header column 3 header<br>column 1 header column 6 header<br>column 2 header column 4 header column 5 header<br>Press any key to continue<br></pre>

<pre><span lang="en-ca">			</span></pre>

<pre><span lang="en-ca">				</span> <a href="game24.htm"><img src="picture/back.gif" style="border: medium none ;" alt="back.gif (341 bytes)" height="35" width="32"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="index.htm"><img src="picture/up.gif" style="border: medium none ;" alt="up.gif (335 bytes)" height="32" width="35"></a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="picture/next.gif" style="border: medium none ;" alt="next.gif (337 bytes)" height="35" width="32"> </pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;</p>

</body></html>