<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"><span lang="en-ca"><font size="6" color="#FF0000"><b>
Dependency(Improved)</b></font></span></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca"> Second </span>edition</font></b></pre>
</div>
<div align="left">
  <pre><b><font size="3">This is <span lang="en-ca">second</span></font><span lang="en-ca"><font size="3"> edition of my dependency class.</font></span></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">
  <pre><span lang="en-ca"><font size="3"><b>The problem is going into details. Suppose you want to list all pre-requisite courses, how should you</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>do? You have to update the dependency link list whenever one node is defined. And continually check</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3"><b>to see if new definition of a node can be found. </b></font></span></pre>
</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 size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>The manipulation of link list is a painful job! Suppose 
  you want to merge two link list to make one </b></span>
</div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>to contain the union set of all two nodes. How should 
  you do? </b></span>
</div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>The topological sort of this kind of dependency graph is 
  actually use DFS and BFS. Originally I want</b></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>to avoid recursive call to improve efficiency. That is 
  why I wrote two useless simple class--</b></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><b>SimpleStack and SimpleQueue. DFS is difficult to 
  implement with a stack instead of recursion.</b></span></div>
<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><b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<pre>#include &lt;iostream&gt;

using namespace std;

const int MaxListSize=40;

struct Link
{
	int data;
	Link* next;
};

struct Vertex
{
	int mark;
	char* str;
	Link* depend;
};

template&lt;class T&gt;
class SimpleStack
{
private:
	T lst[MaxListSize];
	int top;
public:
	SimpleStack(){ top=0;}
	void push(T&amp; t){ lst[top++]=t;}
	T pop(){return lst[--top];}
	bool empty(){ return top==0;}
};

template&lt;class T&gt;
class SimpleQueue
{
private:
	T lst[MaxListSize];
	int head, tail;
public:
	SimpleQueue(){ head=tail=0;}
	void enqueue(T&amp; t){ lst[tail++]=t; tail%=MaxListSize;}
	void dequeue(T&amp; t) { t=lst[head++]; head%=MaxListSize;}
	int length(){return (tail-head)%MaxListSize;}
};


class Depend
{
private:
	Vertex* lst[MaxListSize];
	int size;
	void addNode(const char* str);
	void addSon(int index, int son);
	void DFS();
	void BFS();
	void initMark(bool useDFS);
	void printNode(int index);
	void doDFS(int index);
	void update(int index);
	void mergeLink(int i, int index);
	Link* insertLink(Link* father);
	bool find(Link* head, int key);
	void appendData(int index, int son);
public:
	Depend();
	~Depend();
	int getSize() { return size;}
	int find(const char* str);
	bool append(const char* str);
	bool remove(const char* str);
	void readFromFile(const char* fileName);
	void addDepend(int index, const char* str);
	void print();
	void topsort(bool useDFS=true);

};


int main()
{
	Depend D;
	D.readFromFile(&quot;c:\\depend.txt&quot;);
	D.print();
	cout&lt;&lt;&quot;\nDFS topsort\n&quot;;
	D.topsort(true);
	cout&lt;&lt;&quot;\nBFS topsort\n&quot;;
	D.topsort(false);
	cout&lt;&lt;endl;

	return 0;
}

void Depend::appendData(int index, int son)
{
	Link* target=lst[index]-&gt;depend;

	if (lst[index]-&gt;depend==NULL)
	{
		lst[index]-&gt;depend=new Link;
		target=lst[index]-&gt;depend;
		target-&gt;data=son;
		target-&gt;next=NULL;
		return;
	}

	//find the tail which is the last non-NULL node
	while (target-&gt;next!=NULL)
	{
		target=target-&gt;next;
	}
	target-&gt;next=new Link;
	target-&gt;next-&gt;data=son;
	target-&gt;next-&gt;next=NULL;
}

bool Depend::find(Link* head, int key)
{
	while (head!=NULL)
	{
		if (head-&gt;data==key)
		{
			return true;
		}
		head=head-&gt;next;
	}
	return false;
}


//head has at least one node
void Depend::mergeLink(int i, int index)
{
	Link* source=lst[index]-&gt;depend;
	Link* target=lst[i]-&gt;depend;

	while (source!=NULL)
	{
		if (!find(target, source-&gt;data))
		{
			appendData(i, source-&gt;data);
		}
		source=source-&gt;next;
	}
}

void Depend::update(int index)
{
	Link* temp;
	for (int i=0; i&lt;size; i++)
	{
		temp=lst[i]-&gt;depend;
		if (find(temp, index))
		{
			mergeLink(i, index);
		}

	}
}

	
void Depend::printNode(int index)
{
	cout&lt;&lt;&quot;no.&quot;&lt;&lt;index&lt;&lt;&quot;: &quot;&lt;&lt;lst[index]-&gt;str&lt;&lt;&quot;  &quot;;
}

void Depend::initMark(bool useDFS)
{
	Link* temp;
	for (int i=0; i&lt;size; i++)
	{
		lst[i]-&gt;mark=0;		
	
	}
	if (useDFS)
	{
		return;//do nothing;
	}
	for (i=0; i&lt;size; i++)
	{
		temp=lst[i]-&gt;depend;
		while (temp!=NULL)
		{
			lst[temp-&gt;data]-&gt;mark++;
			temp=temp-&gt;next;
		}
	}
}

void Depend::doDFS(int index)
{
	Link* temp;

	if (lst[index]-&gt;mark!=0)
	{	
		return;
	}
	temp = lst[index]-&gt;depend;
	while (temp!=NULL)
	{
		doDFS(temp-&gt;data);
		temp=temp-&gt;next;
	}
	printNode(index);
	lst[index]-&gt;mark=1;
	
}

void Depend::DFS()
{
	for (int index=0; index&lt;size; index++)
	{
		doDFS(index);		
	}
}

void Depend::BFS()
{
	SimpleQueue&lt;int&gt; Q;
	Link* temp;
	int index;
	for (int i=0; i&lt;size; i++)
	{
		if (lst[i]-&gt;mark==0)
		{
			Q.enqueue(i);		
		}
	}
	while (Q.length()!=0)
	{
		Q.dequeue(index);
		printNode(index);
		temp=lst[index]-&gt;depend;
		while (temp!=NULL)
		{
			lst[temp-&gt;data]-&gt;mark--;
			if (lst[temp-&gt;data]-&gt;mark==0)
			{
				Q.enqueue(temp-&gt;data);
			}
			temp=temp-&gt;next;
		}
	}
}


void Depend::topsort(bool useDFS)
{
	initMark(useDFS);

	if (useDFS)
	{
		DFS();
	}
	else
	{
		BFS();
	}
}
	

void Depend::print()
{
	Link* ptr;
	for (int i=0; i&lt;size; i++)
	{
		cout&lt;&lt;&quot;node no.&quot;&lt;&lt;i&lt;&lt;&quot;:&quot;&lt;&lt;lst[i]-&gt;str&lt;&lt;&quot; : &quot;;
		ptr=lst[i]-&gt;depend;
		while (ptr!=NULL)
		{
			cout&lt;&lt;lst[ptr-&gt;data]-&gt;str&lt;&lt;&quot;  &quot;;
			ptr=ptr-&gt;next;
		}
		cout&lt;&lt;endl;
	}
}

void Depend::addSon(int index, int son)
{
	if (!find(lst[index]-&gt;depend, son))
	{
		appendData(index, son);
	}
	update(son);
}

void Depend::addDepend(int index, const char* str)
{
	int pos= find(str);
	Link* ptr;
	if (pos==-1)
	{
		append(str);
		pos=size-1;//size++
		addSon(index, pos);
	}
	else
	{
		addSon(index, pos);
		ptr= lst[pos]-&gt;depend;
		while (ptr!=NULL)
		{
			addSon(index, ptr-&gt;data);
			ptr=ptr-&gt;next;
		} 
	}
}

void Depend::addNode(const char* str)
{
	char buffer[100];
	int index;
	strcpy(buffer, str);
	char* ptr=buffer;
	ptr=strtok(ptr, &quot; :\n&quot;);

	index=find(ptr);
	if (index==-1)
	{
		append(ptr);
		index=size-1;
	}
	ptr=NULL;
	ptr=strtok(ptr, &quot; :\n&quot;);
	while (ptr!=NULL)
	{
		addDepend(index, ptr);		
		ptr=NULL;
		ptr=strtok(ptr, &quot; :\n&quot;);
	}
	update(index);
}


void Depend::readFromFile(const char* fileName)
{
	FILE* stream;
	char buffer[100];
	if ((stream=fopen(fileName, &quot;r&quot;))==NULL)
	{
		cout&lt;&lt;&quot;fail to read file &quot;&lt;&lt;fileName&lt;&lt;endl;
		return;
	}
	while (fgets(buffer, 100, stream)!=NULL)
	{
		addNode(buffer);
	}
	fclose(stream);
}

Depend::~Depend()
{
	for (int i=0; i&lt;size; i++)
	{
		//delete [] lst[i]-&gt;str;//do we need????
		delete lst[i];
	}
}

Depend::Depend()
{
	size=0;
}

int Depend::find(const char* str)
{
	for (int i=0; i&lt;size; i++)
	{
		if (strcmp(str, lst[i]-&gt;str)==0)
		{
			return i;
		}
	}
	return -1;
}


bool Depend::append(const char* str)
{
	if (find(str)!=-1)
	{
		return false;
	}	
	lst[size]=new Vertex;
	lst[size]-&gt;mark=0;
	lst[size]-&gt;depend=NULL;
	lst[size]-&gt;str=new char[strlen(str)+1];
	strcpy(lst[size]-&gt;str, str);
	size++;
	return true;
}

bool Depend::remove(const char* str)
{
	int index = find(str);
	if (index==-1)
	{
		return false;
	}
	delete [] lst[index]-&gt;str;
	lst[index]-&gt;str=NULL;
	delete lst[index];
	size--;
	for (int i=index; i&lt;size; i++)
	{
		lst[i]=lst[i+1];
	}
	return true;
}


</pre>
<pre>
</pre>
<pre><font color="#0000FF"><b>Here is the result:<span lang="en-ca">(Note DFS and BFS gives almost opposite result.)</span></b></font></pre>
<pre>node no.0:354 : 352 239 249 238 248
node no.1:352 : 239 249 238 248
node no.2:442 : 229 335 352 239 249 228 248 238
node no.3:229 : 228 248
node no.4:335 : 239 238 249 248
node no.5:465 : 335 352 239 249 238 248
node no.6:472 : 352 239 249 238 248
node no.7:473 : 352 239 249 238 248
node no.8:353 : 352 239 249 238 248
node no.9:346 : 229 352 239 249 228 248 238
node no.10:326 : 346 229 352 239 249 228 248 238
node no.11:239 : 238
node no.12:249 : 238 248
node no.13:228 :
node no.14:248 :
node no.15:238 :
node no.16:348 : 249 238 248

DFS topsort
no.15: 238 no.11: 239 no.14: 248 no.12: 249 no.1: 352 no.0: 354 no.13: 228 no.3: 229 no.4: 3
35 no.2: 442 no.5: 465 no.6: 472 no.7: 473 no.8: 353 no.9: 346 no.10: 326 no.16: 348
BFS topsort
no.0: 354 no.2: 442 no.5: 465 no.6: 472 no.7: 473 no.8: 353 no.10: 326 no.16: 348 no.4: 335
no.9: 346 no.3: 229 no.1: 352 no.13: 228 no.11: 239 no.12: 249 no.15: 238 no.14: 248
Press any key to continue</pre>
<pre><font color="#0000FF"><b>Here is the input file:<span lang="en-ca">(actually these are courses that I am interested in.)</span></b></font></pre>
<pre></pre>
<pre>354 : 352
442 : 229 335 352
465 : 335 352
472 : 352
473 : 352
353 : 352
346 : 229 352
326 : 346
352 : 239 249
229 : 228 248
239 : 238
249 : 238 248
348 : 249
335 : 239 249</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>