<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 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="center"><font size="6" color="#FF0000"><b>DFSArray</b></font></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><b>This is <span lang="en-ca">my first edition of </span>my DFS class implemented with an array. Or you can call it second version of standard</b></pre>
</div>
<div align="left">
  <pre><b>DFS, third version of original DFS class. </b></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">
  <b><font size="2">Does anybody regard array has higher efficiency than linked 
  list? Yes, I think so. Linked list is using pointer</font></b></div>
<div align="left">
  　</div>
<div align="left">
  <b><font size="2">to access an address then the value, or the address is used 
  to access real value. This is typical indirect </font></b></div>
<div align="left">
  　</div>
<div align="left">
  <b><font size="2">addressing mode, right? However, array is simply a kind of 
  offset from beginning address of an array. This the </font></b></div>
<div align="left">
  　</div>
<div align="left">
  <font size="2"><b>reason why I want to re-implement my DFS class with array 
  instead of linked list.</b></font></div>
<div align="left">
  　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  <pre><b>There is nothing special about this new version except that an internal static array of DFS* is used to store </b></pre>
</div>
<div align="left">
  <pre><b>all nodes and all nodes is accessed with the index of this array. Most features of old standard DFS class were</b></pre>
</div>
<div align="left">
  <pre><b>kept. </b></pre>
</div>
<div align="left">
  <pre><b><font size="5" color="#FF0000">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><b>1.<span lang="en-ca"> </span></b><span lang="en-ca"><b>void DFS::beginCount(int max, bool findall)</b></span></pre>
</div>
<div align="left">
  <pre><b>This major public function sets up the searching maximum depth and option if all result should be searched.</b></pre>
</div>
<div align="left">
  <pre><b>Whenever a new level of new nodes are generated, move first to the first son node and test user-defined function--</b></pre>
</div>
<div align="left">
  <pre><b>evaluate() to see if result reached. After show result, test if all result should be searched. Then test if user-</b></pre>
</div>
<div align="left">
  <pre><b>defined maximum level is reached. If yes, try next brother node, then rebound for higher level nodes. When going</b></pre>
</div>
<div align="left">
  <pre><b>upper level, delete all those visited nodes to save memory. </b></pre>
</div>
<div align="left">
  <pre><b>2. void DFS::backTrack()</b></pre>
</div>
<div align="left">
  <pre><b>This utility function is quite useful and maybe used repeatedly in different situations. It save all data of nodes</b></pre>
</div>
<div align="left">
  <pre><b>in an internal array.</b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="5" color="#FF0000"><b>E</b></font></span><b><font color="#ff0000" size="5">.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b>1.<span lang="en-ca"> Are you kidding? For such a trivial program?</span></b></pre>
</div>
<pre>　</pre>
<pre>#include &lt;iostream&gt;

using namespace std;

const int MaxSonCount=8;

const int MaxLevel =20;

const int MaxOptions = 10;

const int MaxNodeCount = 1000;

class DFS
{
private:
	void initialize(DFS* now);
	static DFS* nodeList[MaxNodeCount];
	static bool findAll;
	static int optionArray[MaxOptions];
	static int optionCount;
	static char** nameString;
	static int solutionCount;
	static int maxLevel;
	static int domino;
	void addSon(int sonData);
	bool touchDown();
	void setMaxLevel(int max) { maxLevel = max;}
	DFS* upDate();
	bool hasBrother();
	DFS* nextBrother();
	bool generate();
	DFS* findNext();
	DFS* getNode(int theIndex){return nodeList[theIndex];}
	void putNode(int theIndex) { nodeList[theIndex] = this;}
	DFS* getParent(){return getNode(parent);}
	bool hasParent(){return parent!=-1;}
protected:
	int parent;
	int sonCount;
	int sonIndex;
	int son;
	int depth;
	int index;//index in nodeList
	int data;
	void backTrack();
	static int trackRecord[MaxLevel];
	virtual DFS* createSon();
	virtual bool validateOption(int sonData);	
	virtual void onLeave();
	virtual bool evaluate();
	virtual void collectResult();
public:
	int getSolutionCount(){ return solutionCount;}
	void setOptions(int* array, int size);
	void setNameStr(char** str){nameString = str;}
	void beginCount(int max, bool findall=false);
};

int DFS::domino = 0;
bool DFS::findAll = false;
int DFS::maxLevel = 0;
int DFS::optionArray[MaxOptions] = {0};
char** DFS::nameString=NULL;
int DFS::solutionCount = 0;
int DFS::optionCount = 0;
DFS* DFS::nodeList[MaxNodeCount] = {NULL};
int DFS::trackRecord[MaxLevel]= {0};


enum AxixType
	{X,Y,Z};
char* directionString[3] = {&quot;X&quot;,&quot;Y&quot;,&quot;Z&quot;};
int restrict[3] = {3, 2, 4};
int axis[3] = {X,Y,Z};

class SpaceSpider: public DFS
{
protected:
	virtual DFS* createSon();
	virtual bool validateOption(int sonData);	
//	virtual void onLeave();
	virtual bool evaluate();
//	virtual void collectResult();

};


int main()
{
	SpaceSpider R;
	R.setOptions(axis, 3);
	R.setNameStr(directionString);
	R.beginCount(9, true);
	cout&lt;&lt;&quot;Total number is &quot;&lt;&lt;R.getSolutionCount()&lt;&lt;endl;

	return 0;
}





DFS* SpaceSpider::createSon()
{
	DFS* ptr= new SpaceSpider;
	return ptr;
}

bool SpaceSpider::validateOption(int sonData)
{
	int temp[3] = {0};
	backTrack();
	temp[sonData]++;
	for (int i=0; i&lt;depth; i++)
	{
		temp[trackRecord[i]]++;
		if (temp[trackRecord[i]]&gt;restrict[trackRecord[i]])
		{
			return false;
		}
	}
	return true;
}

bool SpaceSpider::evaluate()
{
	return depth==9;
}

//I don't know what extra work to be for the time being
bool DFS::evaluate()
{
	return true;
}

bool DFS::touchDown()
{
	return depth==maxLevel;
}

void DFS::onLeave()
{
	DFS* ptr =this;
	int end = ptr-&gt;index;
	int start;
	if (ptr-&gt;hasParent())
	{
		start = ptr-&gt;getParent()-&gt;son;
		for (int i= start; i&lt;=end;i++)
		{
			ptr = getNode(i);
			delete ptr;
			nodeList[i] = NULL;
		}
		domino = domino + start - end -1;
	}	
}

void DFS::backTrack()
{
	DFS* ptr = this;

	while (ptr-&gt;hasParent())
	{
		trackRecord[ptr-&gt;depth-1] = ptr-&gt;data;
		ptr = ptr-&gt;getParent();
	}
}


//a stack
void DFS::collectResult()
{
	backTrack();
	cout&lt;&lt;&quot;The route is:&quot;;
	for (int i=0; i&lt;depth; i++)
	{
		cout&lt;&lt;nameString[trackRecord[i]]&lt;&lt;&quot;, &quot;;
	}
	cout&lt;&lt;&quot;It is number:&quot;&lt;&lt;solutionCount++;
	cout&lt;&lt;endl;
}

void DFS::setOptions(int *array, int size)
{
	optionCount = size;
	for (int i=0; i&lt;size; i++)
	{
		optionArray[i] = *(array+i);
	}
}


//this is supposed to be overrided by user
bool DFS::validateOption(int sonData)
{
	return true;
}

void DFS::beginCount(int max, bool findall)
{
	DFS* ptr = this;
	setMaxLevel(max);
	findAll = findall; //setup if want all result
	initialize(this);

	while (ptr!=NULL)
	{
		if (ptr-&gt;generate())
		{
			ptr = ptr-&gt;upDate();//move to first son
			if (ptr-&gt;evaluate())
			{
				ptr-&gt;collectResult();
				if (!findAll)
				{
					break;
				}
				else
				{
					ptr = ptr-&gt;findNext();
				}
			}
			else
			{
				if (ptr-&gt;touchDown())
				{
					ptr=ptr-&gt;findNext();
				}
			}
		}
		else
		{
			ptr = ptr-&gt;findNext();
		}
	}
	if (solutionCount==0)
	{
		cout&lt;&lt;&quot;no solution!&quot;;
	}		
}
	
DFS* DFS::findNext()
{
	DFS* ptr = this;
	DFS* dummy;
	while (ptr!=NULL)
	{
		if (ptr-&gt;hasBrother())
		{
			return getNode(ptr-&gt;index+1);//next brother			
		}
		else
		{
			if (ptr-&gt;hasParent())
			{
				dummy = ptr;
				ptr = ptr-&gt;getParent(); //if 
				dummy-&gt;onLeave(); //only clear when go up one level
			}
			else
			{
				break;
			}
		}
	}
	return NULL;
}

bool DFS::generate()
{
	DFS* ptr= this;
	bool result = false;
	//this is preorder and I don't bother to 
	//give choices for midorder or postorder
	for (int i=0; i&lt; optionCount; i++)
	{
		if (validateOption(optionArray[i]))
		{
			addSon(optionArray[i]);
			result = true;		
		}
	}
	return result;
}

DFS* DFS::upDate()
{
	//return first son
	return getNode(son);
}

//must be override by user when inherited
DFS* DFS::createSon()
{
	DFS* ptr = new DFS;
	return ptr;
}

void DFS::addSon(int sonData)
{	
	if (sonCount+1&lt;MaxSonCount)
	{
		if (domino==MaxNodeCount)
		{
			cout&lt;&lt;&quot;Exceeds limit of node list&quot;&lt;&lt;endl;
			return;
		}
		DFS* ptr = createSon();
		ptr-&gt;index = domino;//
		ptr-&gt;putNode(domino);		

		if (sonCount==0)//if it is the first son
		{
			son = domino;//first son 
		}
		domino++;
		ptr-&gt;data = sonData;
		ptr-&gt;sonCount = 0;
		ptr-&gt;son = -1;//temporarily
		ptr-&gt;parent = index;
		ptr-&gt;depth = depth+1;
		ptr-&gt;sonIndex = sonCount;
		sonCount++;
	}
	else
	{
		cout&lt;&lt;&quot;Exceed max of sons!&quot;;
	}
}

void DFS::initialize(DFS* now)
{
	now-&gt;index =0;	
	now-&gt;depth = 0;
	now-&gt;sonCount = 0;
	now-&gt;sonIndex = -1;
	now-&gt;parent = -1;
	now-&gt;data = 0;
	now-&gt;putNode(0); //put in list
	domino++;
}

bool DFS::hasBrother()
{
	if (hasParent())
	{
		if (getParent()-&gt;sonCount &gt; sonIndex+1)//has little brother
		{
			return true;
		}
	}
	return false;
}
</pre>
<pre>
</pre>
<pre>
</pre>
<pre><b><font color="#FF0000" size="3"><span lang="en-ca"><a name="result"></a>Running result of program:</span></font></b></pre>
<pre>I want to test my new class, so I choose the old problem---the space spider who is crawling in 3-D for 9 steps in which it can only</pre>
<pre>go X-axis 3 steps, Y-axis 2 steps, Z-axis 4 steps. <a href="spider.htm">This problem</a> has been solved before.</pre>
<pre>
...</pre>
<pre>...</pre>
<pre>The route is:Z, Z, Z, X, Z, Y, X, X, Y, It is number:1227
The route is:Z, Z, Z, X, Z, Y, X, Y, X, It is number:1228
The route is:Z, Z, Z, X, Z, Y, Y, X, X, It is number:1229
The route is:Z, Z, Z, Y, X, X, X, Y, Z, It is number:1230
The route is:Z, Z, Z, Y, X, X, X, Z, Y, It is number:1231
The route is:Z, Z, Z, Y, X, X, Y, X, Z, It is number:1232
The route is:Z, Z, Z, Y, X, X, Y, Z, X, It is number:1233
The route is:Z, Z, Z, Y, X, X, Z, X, Y, It is number:1234
The route is:Z, Z, Z, Y, X, X, Z, Y, X, It is number:1235
The route is:Z, Z, Z, Y, X, Y, X, X, Z, It is number:1236
The route is:Z, Z, Z, Y, X, Y, X, Z, X, It is number:1237
The route is:Z, Z, Z, Y, X, Y, Z, X, X, It is number:1238
The route is:Z, Z, Z, Y, X, Z, X, X, Y, It is number:1239
The route is:Z, Z, Z, Y, X, Z, X, Y, X, It is number:1240
The route is:Z, Z, Z, Y, X, Z, Y, X, X, It is number:1241
The route is:Z, Z, Z, Y, Y, X, X, X, Z, It is number:1242
The route is:Z, Z, Z, Y, Y, X, X, Z, X, It is number:1243
The route is:Z, Z, Z, Y, Y, X, Z, X, X, It is number:1244
The route is:Z, Z, Z, Y, Y, Z, X, X, X, It is number:1245
The route is:Z, Z, Z, Y, Z, X, X, X, Y, It is number:1246
The route is:Z, Z, Z, Y, Z, X, X, Y, X, It is number:1247
The route is:Z, Z, Z, Y, Z, X, Y, X, X, It is number:1248
The route is:Z, Z, Z, Y, Z, Y, X, X, X, It is number:1249
The route is:Z, Z, Z, Z, X, X, X, Y, Y, It is number:1250
The route is:Z, Z, Z, Z, X, X, Y, X, Y, It is number:1251
The route is:Z, Z, Z, Z, X, X, Y, Y, X, It is number:1252
The route is:Z, Z, Z, Z, X, Y, X, X, Y, It is number:1253
The route is:Z, Z, Z, Z, X, Y, X, Y, X, It is number:1254
The route is:Z, Z, Z, Z, X, Y, Y, X, X, It is number:1255
The route is:Z, Z, Z, Z, Y, X, X, X, Y, It is number:1256
The route is:Z, Z, Z, Z, Y, X, X, Y, X, It is number:1257
The route is:Z, Z, Z, Z, Y, X, Y, X, X, It is number:1258
The route is:Z, Z, Z, Z, Y, Y, X, X, X, It is number:1259
Total number is 1260
Press any key to continue</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; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></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)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>