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

<body>

<blockquote>

<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#FF0000" size="6"><b> 
</b></font><font color="#FF0000" size="6"><b>Power Dictionary</b></font>    
</p>
</blockquote>
<div align="left">
  <pre><b><font color="#ff0000" size="5">B.Second Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is the second edition of my dictionary and it is very powerful now!</b></pre>
</div>
<div align="left">
  <pre><b>1¡£ Basic idea: I want to add two features to my original dictionary(in fact they seem to be same, yet...). One</b></pre>
</div>
<div align="left">
  <pre><b>is the &quot;frequency&quot; which means how many times the word actually is encountered. It is a very important statistic</b></pre>
</div>
<div align="left">
  <pre><b>data to be stored in file. So, I have to change the &quot;saveToFile&quot; method to add this data.(Actually I add this </b></pre>
</div>
<div align="left">
  <pre><b>to their ancester---Tree class). Second data is &quot;Rank&quot; which means which position of this word is in total words</b></pre>
</div>
<div align="left">
  <pre><b>in view of &quot;frequency&quot;. So, it is a data connected with &quot;frequency&quot; and is not necessary to be save to file. However,</b></pre>
</div>
<div align="left">
  <pre><b>it need to be updated frequently which is not so easy after the total quantity of words increasing. So, I still </b></pre>
</div>
<div align="left">
  <pre><b>use the basic &quot;binary search tree&quot; to solve the rank problem with changing the &quot;compare method&quot; of RankTree to be</b></pre>
</div>
<div align="left">
  <pre><b>with the &quot;frequency&quot; characteristic instead of &quot;key&quot;. In other word, key is &quot;frequency&quot; instead of &quot;name&quot;.( but not</b></pre>
</div>
<div align="left">
  <pre><b>exactly, as frequency is often same, and in this case, I compare &quot;key&quot; or &quot;name&quot;, otherwise, there will be too </b></pre>
</div>
<div align="left">
  <pre><b>many same rank word.)</b><b> </b></pre>
</div>
<div align="left">
  <pre><b>2¡£ Program design: </b><b>The biggest problem is how to walk round the &quot;key&quot; problem and still use the original &quot;insert&quot;</b></pre>
</div>
<div align="left">
  <pre><b>method. It is only way to setup a new class--RankTree which overload the operator &quot;&lt;&quot; and &quot;&gt;&quot; so that the &quot;insert&quot;</b></pre>
</div>
<div align="left">
  <pre><b>method will correctly use &quot;frequency&quot; to compare first during &quot;inserting&quot; procedure. The other big problem is that</b></pre>
</div>
<div align="left">
  <pre><b>I realized how necessary to make a &quot;real call back&quot; function for &quot;traverse&quot; the whole tree along with a user defined</b></pre>
</div>
<div align="left">
  <pre><b>data pointer inside the user defined &quot;visit&quot; method when visiting each node of tree. So, I overload the &quot;traverse&quot;</b></pre>
</div>
<div align="left">
  <pre><b>method of Tree class to allow user sending his own data by parameter &quot;userPtr&quot;. Then I easily rank each word by </b></pre>
</div>
<div align="left">
  <pre><b>this callback function.</b></pre>
</div>
<div align="left">
  <pre>¡¡</pre>
</div>
<div align="left">
  <pre><b>3¡£ Major function£º</b></pre>
</div>
<div style="WIDTH: 892px; HEIGHT: 102px" align="left">
  <pre><b>     A. void Tree::traverse(void (*visit)(Tree* node, void* userPtr), void* userPtr, 
		TraverseOrder defaultOrder)</b></pre>
  <pre><b>	This is the callback function with one more user defined data pointer &quot;userPtr&quot;, and I actually use it to </b></pre>
  <pre><b>	transfer the rank data to let it increment one by one.</b></pre>
  <pre><b>	B. void RankTree::setRankTree(WordTree* wordRoot)</b></pre>
  <pre><b>	This is the heart function of using new class RankTree to set up a new &quot;forest&quot; of RankTrees with &quot;frequency&quot;</b></pre>
  <pre><b>	as first primary &quot;key&quot; which means &quot;compare&quot; with &quot;freq&quot; first, &quot;key&quot; second if &quot;freq&quot; are same. It is quite</b></pre>
  <pre><b>	important that you must setup a root for this &quot;RankTree forest&quot;, as &quot;insert&quot; method....Oh my god! It is</b></pre>
  <pre><b>	not necessary to differenciate the root with all other nodes, right? I will try later.</b></pre>
  <pre><b>	C. bool RankTree::operator &lt;(Tree&amp; node);  bool RankTree::operator &gt;(Tree&amp; node);</b></pre>
  <pre><b>	I overload these two function instead of so-called &quot;compare&quot; method, as when I designed I didn't realize</b></pre>
  <pre><b> 	the need to put both &quot;rank&quot;&amp;&quot;frequency&quot; into ancester class---Tree. Now, it is better to override &quot;compare&quot;</b></pre>
  <pre><b>	method.</b></pre>
  <pre>¡¡</pre>
  <pre><b>4¡£ Further improvement£º</b></pre>
  <pre><b>	A. I have to go soon, so, no more time.</b></pre>
  <pre><b>	B. Override &quot;compare&quot; method instead of &quot;&lt;,&gt;&quot;. try to make simple way of &quot;setRankTree&quot; method, as my &quot;insert&quot;</b></pre>
  <pre><b>	method is so perfect, no need to do some extra judgement for root.</b></pre>
  <pre><b>	</b></pre>
</div>
<div align="left">
  <pre><b>		</b></pre>
</div>
<pre>#include &lt;iostream&gt;
#include &lt;cstdlib&gt;
#include &lt;cstring&gt;
#include &lt;fstream&gt;
#include &lt;ctime&gt;</pre>
<pre>using namespace std;
</pre>
<pre>const MaxWordLength = 255;</pre>
<pre>enum TraverseOrder
{
	PREORDER, MIDORDER, POSTORDER
};
</pre>
<pre>class Tree
{
private:	
	Tree* pLeft;
	Tree* pRight;
	Tree* pParent;
	char* pName;
	int index;
	static int treeCounter;
	static Tree* pRoot;
	int freq;
	int rank;
	void preWalk(Tree* node, void (*visit)(Tree* node));
	void midWalk(Tree* node, void (*visit)(Tree* node));
	void postWalk(Tree* node, void (*visit)(Tree* node));
	void preWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr);
	void midWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr);
	void postWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr);
protected:
	void* pKey;
public:
	const int getRank() { return rank;}
	void setRank(const int newRank) { rank = newRank;}
	const int getFreq() {return freq;}
	void setFreq(const int newFreq) { freq = newFreq;}
	void setFreq() {freq++;}
	Tree* left();
	Tree* right();
	Tree* parent();
	virtual void* key();
	virtual void setKey(void* newKey);
	void setRoot(Tree* node);
	const char* name();
	const int getIndex();
	void setLeft(Tree* leftSon);
	void setRight(Tree* rightSon);
	void setParent(Tree* father);
	void setIndex(const int number);
	virtual	int compare(const void* otherKey); 
	void setName(const char *str);
	void giveBirth();
	virtual bool operator&gt;(Tree&amp;);
	virtual bool operator==(Tree&amp;);
	virtual bool operator&lt;(Tree&amp;);	
	Tree();
	virtual ~Tree();
	static Tree* root() {return pRoot;}
	const int count();
	void traverse(void ( *visit)(Tree* node), TraverseOrder defaultOrder= MIDORDER);
	void traverse(void (*visit)(Tree* node, void* userPtr), void* userPtr, 
		TraverseOrder defaultOrder = MIDORDER);
};
</pre>
<pre>void visitRank(Tree* node, void* userPtr);</pre>
<pre>void defaultVisit(Tree* node);</pre>
<pre>class BinaryTree: public Tree
{
private:
	</pre>
<pre>public:
	virtual void remove(BinaryTree* node);
	virtual BinaryTree* next();
	virtual BinaryTree* prev();
	virtual bool insert(BinaryTree* node);
	virtual ~BinaryTree();</pre>
<pre>};</pre>
<pre>class WordTree: public BinaryTree
{
private:
	static int wordLength;
	static int wordCounter;
	WordTree* addNode(WordTree* node, FILE** stream);
	</pre>
<pre>protected:
	void setWordCounter();
	void readWord(FILE** file);
	void addWord(char* buffer);
public:</pre>
<pre>	WordTree* readNode(WordTree* node, FILE** stream);
	WordTree* readFromFile(const char* fileName);
	void saveNode(WordTree* node, FILE** stream);
	virtual int compare(const void *otherKey);
	void setWordLength(const int newLength);
	static const int getWordLength();
	virtual void setKey(void* newKey);
	virtual bool operator&gt;(Tree&amp;);
	virtual bool operator==(Tree&amp;);
	virtual bool operator&lt;(Tree&amp;);
	void openFile(const char* fileName);
	WordTree(const char * fileName);
	WordTree();
	int wordCount();
	virtual void setName(const char *str);
	void saveToFile(const char* fileName);
	~WordTree();
	WordTree* findWord(const char* buffer);
};</pre>
<pre>class RankTree: public WordTree
{
private:
	static RankTree* rankRoot;
public:	
	virtual bool operator&gt;(Tree&amp; node);
	virtual bool operator&lt;(Tree&amp; node);
	void setRankTree(WordTree* wordRoot);
	</pre>
<pre>	RankTree();
	
</pre>
<pre>};
</pre>
<pre>int count=0;
</pre>
<pre>int main()
{
	WordTree *ptr = new WordTree;
	char choice[6], fileName[30];</pre>
<pre>	ptr = ptr-&gt;readFromFile(&quot;c:\\nickback.txt&quot;);
	cout&lt;&lt;&quot;quit? or input?\nEnter your choice: \n&quot;;
	cin&gt;&gt;choice;
	while (strcmp(choice, &quot;quit&quot;)!=0&amp;&amp;strcmp(choice, &quot;input&quot;)!=0)
	{
		cout&lt;&lt;&quot;quit? or input?\n Enter your choic: \n&quot;;
		cin&gt;&gt;choice;
	}
	if (strcmp(choice, &quot;quit&quot;)==0)
	{
		cout&lt;&lt;&quot;The total number of words in dictionary is &quot;&lt;&lt;ptr-&gt;wordCount()&lt;&lt;endl;
		return 0;
	}
	else
	{
		if (strcmp(choice, &quot;input&quot;)==0)
		{
			cout&lt;&lt;&quot;\nnow input file name here(input 'quit' to exit):\n&quot;;
			cin&gt;&gt;fileName;
			while (strcmp(fileName, &quot;quit&quot;)!=0)
			{
				ptr-&gt;openFile(fileName);
				cout&lt;&lt;&quot;\nnow input file name here(input quit to exit):\n&quot;;
				</pre>
<pre>				cin&gt;&gt;fileName;
			}
			cout&lt;&lt;&quot;\nDo you want to see contents?(yes or no)\n&quot;;
			</pre>
<pre>			
			cin&gt;&gt;choice;
			if (strcmp(choice, &quot;yes&quot;)==0)
			{
				ptr-&gt;traverse(defaultVisit, PREORDER);
			}</pre>
<pre>			cout&lt;&lt;&quot;\nDo you want to rank the tree?(yes or no)\n&quot;;
			cin&gt;&gt;choice;
			if (strcmp(choice, &quot;yes&quot;)==0)
			{
				int rankCount =0;
				RankTree *rankPtr = new RankTree;
				rankPtr-&gt;setRankTree(ptr);
				rankPtr-&gt;traverse(visitRank, (void*)(&amp;rankCount), MIDORDER);
				rankPtr-&gt;traverse(defaultVisit, PREORDER);
			}
			cout&lt;&lt;&quot;The total number of words in dictionary is &quot;&lt;&lt;ptr-&gt;wordCount();
			ptr-&gt;saveToFile(&quot;c:\\nickback.txt&quot;);
		}
	}</pre>
<pre>	return 0;
}</pre>
<pre>int WordTree::wordCounter = 0;
int WordTree::wordLength = 20;
RankTree* RankTree::rankRoot = NULL;</pre>
<pre>RankTree::RankTree()
{
	if (rankRoot == NULL)
	{
		rankRoot = this;
	}
}</pre>
<pre>void visitRank(Tree* node, void* userPtr)
{
	node-&gt;setRank(*(int*)(userPtr));
	*(int*)(userPtr) +=1;
	</pre>
<pre>}
</pre>
<pre>bool RankTree::operator &lt;(Tree&amp; node)
{
	int result;
	result = getFreq() - node.getFreq();
	if (result !=0)
	{
		return (result&lt;0);
	}
	else
	{
		return (strcmp((char*)key(), (char*)node.key())&lt;0);
	}
}</pre>
<pre>bool RankTree::operator &gt;(Tree&amp; node)
{
	int result;
	result = getFreq() - node.getFreq();
	if (result !=0)
	{
		return (result&gt;0);
	}
	else
	{
		return (strcmp((char*)key(), (char*)node.key())&gt;0);
	}
}
</pre>
<pre>void RankTree::setRankTree(WordTree* wordRoot)
{
	RankTree* ptr;</pre>
<pre>	if (wordRoot!=NULL)
	{
		if (this-&gt;root()!=NULL)
		{
			ptr = new RankTree;
			ptr-&gt;setFreq(wordRoot-&gt;getFreq());
			ptr-&gt;setKey((void*)wordRoot-&gt;key());
			ptr-&gt;insert(ptr);
		}
		else
		{
			this-&gt;setRoot(this);
			this-&gt;setFreq(wordRoot-&gt;getFreq());
			this-&gt;setKey((void*)wordRoot-&gt;key());
		}
</pre>
<pre>		setRankTree((WordTree*)wordRoot-&gt;left());
		setRankTree((WordTree*)wordRoot-&gt;right());
	}
</pre>
<pre>}
</pre>
<pre>BinaryTree::~BinaryTree()
{</pre>
<pre>}
</pre>
<pre>WordTree::~WordTree()
{
	</pre>
<pre>}</pre>
<pre>void WordTree::setWordCounter()
{
	wordCounter ++;
}</pre>
<pre>const int WordTree::getWordLength()
{
	return wordLength;
}</pre>
<pre>WordTree* WordTree::addNode(WordTree* node, FILE** stream)
{
	char buffer[MaxWordLength];
	int index, pIndex, number;
	WordTree *domino;
	char *ptr=buffer, ch;
	</pre>
<pre>	fread((void*)(&amp;index), sizeof(int), 1, *stream);
	fread((void*)(&amp;pIndex), sizeof(int), 1, *stream);
</pre>
<pre>	if (index==-1&amp;&amp;pIndex==-1)
	{
		return NULL;
	}</pre>
<pre>	do
	{
		ch = fgetc(*stream);
		*ptr = ch;
		ptr++;
	}
	while(ch!='\0');
	fread((void*)(&amp;number), sizeof(int), 1, *stream);
	setWordCounter();  //add a word</pre>
<pre>	if (pIndex== -1)  //this is root
	{			
		node-&gt;setIndex(index);
		node-&gt;setFreq(number);
		node-&gt;setName(buffer);
		node-&gt;setRoot(node);
		return node;
	}</pre>
<pre>	while (pIndex!=node-&gt;getIndex())
	{	
		if (node-&gt;parent()==NULL)
		{
			return NULL;
		}
		node= (WordTree*)node-&gt;parent(); 
	}
</pre>
<pre>	if (node!=NULL&amp;&amp;pIndex==node-&gt;getIndex())
	{
		domino = new WordTree;
		domino-&gt;setIndex(index);
		domino-&gt;setName(buffer);
		domino-&gt;setFreq(number);
		domino-&gt;setParent(node);
		if (*domino&lt;*node)
		{
			node-&gt;setLeft(domino);
		}
		else
		{
			node-&gt;setRight(domino);
		}
		</pre>
<pre>		return domino;
	}
	else
	{
		return NULL;
	}
}
</pre>
<pre>WordTree* WordTree::readNode(WordTree* node, FILE** stream)
{	
	WordTree* domino = node;</pre>
<pre>	while (domino!=NULL)
	{
		domino = addNode(domino, stream);
	}
	return (WordTree*)node-&gt;root();  //this is ugly as I have to remove those sentinal 
}</pre>
<pre>WordTree* WordTree::readFromFile(const char* fileName)
{
	FILE* stream;</pre>
<pre>	if ((stream=fopen(fileName, &quot;r+b&quot;))==NULL)
	{
		cout&lt;&lt;&quot;unable to open file &quot;&lt;&lt;fileName&lt;&lt;endl;
		return NULL;
	}
	else
	{
		WordTree* ptr= new WordTree;
		return readNode(ptr, &amp;stream);	
	}
	fclose(stream);
}</pre>
<pre>void WordTree::saveNode(WordTree* node, FILE** stream)
{
	int first, second, number;</pre>
<pre>	first = node-&gt;getIndex();
	number = getFreq();</pre>
<pre>	fwrite((void*)(&amp;first), sizeof(int), 1, *stream);
	if (node-&gt;parent()==NULL)
	{
		second = -1;		
	}
	else
	{
		second = node-&gt;parent()-&gt;getIndex();		
	}
	fwrite((void*)(&amp;second), sizeof(int), 1, *stream);
	fwrite((void*)(node-&gt;name()),sizeof(char), strlen(node-&gt;name()), *stream);
	fputc('\0', *stream);//I have to put this '/n' otherwise there is always problem!
	fwrite((void*)(&amp;number), sizeof(int), 1, *stream);
}</pre>
<pre>	
void traverseTree(WordTree* node, FILE** stream)
{
	if (node!=NULL)
	{
		node-&gt;saveNode(node, stream);
		traverseTree((WordTree*)node-&gt;left(), stream);
		traverseTree((WordTree*)node-&gt;right(), stream);
	}
}</pre>
<pre>void writeEnd(FILE** stream)
{
	int temp1=-1, temp2=-1;
	fwrite((void*)(&amp;temp1), sizeof(int), 1, *stream);
	fwrite((void*)(&amp;temp2), sizeof(int), 1, *stream);
}</pre>
<pre>void WordTree::saveToFile(const char* fileName)
{
	void traverseTree(WordTree* node, FILE ** stream);
	void writeEnd(FILE** stream);</pre>
<pre>	WordTree *domino;
	</pre>
<pre>	FILE * stream;
	</pre>
<pre>	if ((stream=fopen(&quot;c:\\nickback.txt&quot;, &quot;w+b&quot;))==NULL)
	{
		cout&lt;&lt;&quot;unable to save to file &quot;&lt;&lt;fileName&lt;&lt;endl;
	}
	else
	{
		domino = (WordTree*)root();
		traverseTree((WordTree*)domino, &amp;stream);
	}
	writeEnd(&amp;stream);
	fclose(stream);
}</pre>
<pre>	
const int Tree::count()
{
	return treeCounter;
}</pre>
<pre>void WordTree::setWordLength(const int newLength)
{
	if (newLength&gt;MaxWordLength)
	{
		cout&lt;&lt;&quot;exceed max word length.&quot;&lt;&lt;endl;
	}
	else
	{
		wordLength = newLength;
	}
}</pre>
<pre>int WordTree::compare(const void*otherKey)
{
	return strcmp((char*)key(), (char*)otherKey);
}</pre>
<pre>int WordTree::wordCount()
{
	return wordCounter;
}</pre>
<pre>WordTree::WordTree()
{
	</pre>
<pre>}</pre>
<pre>void WordTree::openFile(const char* fileName)
{
	FILE * stream;	
	if ((stream=fopen(fileName, &quot;r+b&quot;))==NULL)
	{
		cout&lt;&lt;&quot;unable open file!&quot;&lt;&lt;endl;
	}
	else
	{
		readWord(&amp;stream);
	}
	fclose(stream);
}</pre>
<pre>void WordTree::readWord(FILE **stream)
{
	char buffer[MaxWordLength];
	char *ptr = buffer;
	char ch;
	int counter =0;</pre>
<pre>	
	while (!feof(*stream))
	{
		ptr = buffer;
		counter =  0;
		ch = toupper(fgetc(*stream));
		while (isalnum(ch)&amp;&amp;!feof(*stream)&amp;&amp;counter&lt;wordLength)
		{
			*ptr = ch;
			ch = toupper(fgetc(*stream));
			ptr++;
			counter++;
		}</pre>
<pre>		if (ptr!=buffer)
		{
			*ptr='\0';
			addWord(buffer);
		}	
	}
}</pre>
<pre>WordTree* searchWord(WordTree* node, const char* buffer)
{
	int result;
	if (node!=NULL)
	{		
		result = strcmp((char*)(node-&gt;key()), buffer);
		if (result ==0)
		{
			return node;
		}
		else
		{
			if (result &lt; 0)
			{
				return searchWord((WordTree*)node-&gt;right(), buffer);
			}
			else
			{
				return searchWord((WordTree*)node-&gt;left(), buffer);
			}
		}
	}
	else
	{
		return NULL;
	}
}
</pre>
<pre>WordTree* WordTree::findWord(const char *buffer)
{
	WordTree* searchWord(WordTree* node, const char* buffer);
	return searchWord((WordTree*)root(), buffer);
}
</pre>
<pre>void WordTree::addWord(char * buffer)
{
	//need add a findword method and find first and then new
	WordTree *ptr;
	ptr = findWord(buffer);
	if (ptr==NULL)
	{
		ptr = new WordTree;
	</pre>
<pre>		ptr-&gt;setName(buffer);    
		if (ptr-&gt;insert(ptr))
		{
			setWordCounter();
		}	
	}
	else
	{
		ptr-&gt;setFreq();
	}
}</pre>
<pre>void WordTree::setName(const char *str)
{
	Tree::setName(str);
	setKey((void*)name());
}</pre>
<pre>int Tree::treeCounter= 0;</pre>
<pre>WordTree::WordTree(const char* fileName)
{
	WordTree::WordTree();
	openFile(fileName);
}</pre>
<pre>void WordTree::setKey(void * newKey)
{
	pKey = newKey;
}</pre>
<pre>bool WordTree::operator &lt;(Tree&amp; second)
{
	if (strcmp((char*)key(), (char*)second.key())&lt;0)
	{
		return true;
	}
	else
	{
		return false;
	}
}</pre>
<pre>bool WordTree::operator ==(Tree&amp; second)
{
	if (strcmp((char*)key(), (char*)second.key())==0)
	{
		return true;
	}
	else
	{
		return false;
	}
}</pre>
<pre>bool WordTree::operator &gt;(Tree&amp; second)
{
	if (strcmp((char*)key(), (char*)second.key())&gt;0)
	{
		return true;
	}
	else
	{
		return false;
	}
}</pre>
<pre>void defaultVisit(Tree* node)
{
	cout&lt;&lt;&quot;\n\n&quot;;
	cout&lt;&lt;&quot;default visiting tree index:&quot;&lt;&lt;node-&gt;getIndex()&lt;&lt;endl;
	cout&lt;&lt;&quot;and tree name is:&quot;&lt;&lt;node-&gt;name()&lt;&lt;endl;
	cout&lt;&lt;&quot;and its frequency is: &quot;&lt;&lt;(node)-&gt;getFreq()&lt;&lt;endl;
	cout&lt;&lt;&quot;and its rank is:&quot;&lt;&lt;node-&gt;getRank()&lt;&lt;endl;
	if (node-&gt;parent()!=NULL)
	{
		cout&lt;&lt;&quot;its parent is:&quot;&lt;&lt;node-&gt;parent()-&gt;name()&lt;&lt;endl;
		if (node==node-&gt;parent()-&gt;left())
		{
			cout&lt;&lt;&quot;and it is left son.&quot;&lt;&lt;endl;
		}
		else
		{
			cout&lt;&lt;&quot;and it is right son&quot;&lt;&lt;endl;
		}
	}
	else
	{
		cout&lt;&lt;&quot;it has no parent&quot;&lt;&lt;endl;
	}
	cout&lt;&lt;&quot;\n\n&quot;;
}
</pre>
<pre>void Tree::preWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{	
		visit(node);
		preWalk(node-&gt;left(), visit);		
		preWalk(node-&gt;right(), visit);
	}
}

</pre>
<pre>void Tree::postWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{
		postWalk(node-&gt;left(), visit);
		postWalk(node-&gt;right(), visit);
		visit(node);
	}
}</pre>
<pre>void Tree::midWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{
		midWalk(node-&gt;left(), visit);
		visit(node);
		midWalk(node-&gt;right(), visit);
	}
}</pre>
<pre>void Tree::preWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{	
		visit(node, userPtr);
		preWalk(node-&gt;left(), visit, userPtr);		
		preWalk(node-&gt;right(), visit, userPtr);
	}
}
</pre>
<pre>void Tree::midWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{
		midWalk(node-&gt;left(), visit, userPtr);
		visit(node, userPtr);
		midWalk(node-&gt;right(), visit, userPtr);
	}
}</pre>
<pre>void Tree::postWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{
		postWalk(node-&gt;left(), visit, userPtr);
		postWalk(node-&gt;right(), visit, userPtr);
		visit(node, userPtr);
	}
}

</pre>
<pre>void Tree::traverse(void (*visit)(Tree* node, void* userPtr), void* userPtr, 
		TraverseOrder defaultOrder)
{
	Tree *domino;
	domino = root();</pre>
<pre>	switch(defaultOrder)
	{
	case PREORDER:
		preWalk(domino, visit, userPtr);
		break;
	case MIDORDER:
		midWalk(domino, visit, userPtr);
		break;
	case POSTORDER:
		postWalk(domino, visit, userPtr);
		break;
	}
}

</pre>
<pre>void Tree::traverse(void (*visit)(Tree* node), TraverseOrder defaultOrder)
{
	Tree *domino;
	domino = root();</pre>
<pre>	switch(defaultOrder)
	{
	case PREORDER:
		preWalk(domino, visit);
		break;
	case MIDORDER:
		midWalk(domino, visit);
		break;
	case POSTORDER:
		postWalk(domino, visit);
		break;
	}
}</pre>
<pre>Tree* Tree::pRoot = NULL;</pre>
<pre>void BinaryTree::remove(BinaryTree* node)
{
	BinaryTree* ptr=NULL;</pre>
<pre>	if (node-&gt;left()==NULL || node-&gt;right()==NULL)
	{
		if (node-&gt;left()!=NULL)
		{
			node-&gt;parent()-&gt;setLeft(node-&gt;left());
			node-&gt;left()-&gt;setParent(node-&gt;parent());
		}
		if (node-&gt;right()!=NULL)
		{
			node-&gt;parent()-&gt;setRight(node-&gt;right());
			node-&gt;right()-&gt;setParent(node-&gt;parent());
		}
	}
	else
	{
		ptr = node-&gt;next();
		remove(ptr);
		ptr-&gt;setParent(node-&gt;parent());
		if (node-&gt;parent()==NULL)
		{
			node-&gt;setRoot(ptr);			
		}
		else
		{
			if (node==node-&gt;parent()-&gt;left())
			{
				node-&gt;parent()-&gt;setLeft(ptr);
			}
			else
			{
				node-&gt;parent()-&gt;setRight(ptr);
			}
			ptr-&gt;setLeft(node-&gt;left());
			ptr-&gt;setRight(node-&gt;right());
		}
	}
}
</pre>
<pre>bool Tree::operator==(Tree&amp; second)
{
	if (this-&gt;compare(second.key())==0)
	{
		return true;
	}
	else
	{
		return false;
	}	
}</pre>
<pre>bool Tree::operator &lt;(Tree&amp; second)
{
	if (this-&gt;compare(second.key())&lt;0)
	{
		return true;
	}
	else
	{
		return false;
	}	
}
</pre>
<pre>bool Tree::operator &gt;(Tree&amp; second)
{
	if (this-&gt;compare(second.key())&gt;0)
	{
		return true;
	}
	else
	{
		return false;
	}	
}</pre>
<pre>int Tree::compare(const void * otherKey)
{
	return *((int*)(key()))- *((int*)(otherKey));
}</pre>
<pre>void* Tree::key()
{
	return pKey;
}</pre>
<pre>void Tree::setKey(void *newKey)
{
	pKey = malloc(sizeof(int));
	*(int*)(pKey) = *(int*)(newKey);
}

</pre>
<pre>void Tree::setRoot(Tree *node)
{
	pRoot = node;
}</pre>
<pre>bool BinaryTree::insert(BinaryTree* node)
{
	Tree* ptr, *dummy;</pre>
<pre>	ptr = root();
	dummy = ptr;
	while (ptr!=NULL)
	{
		dummy = ptr;
		if (*ptr&gt;*node)
		{				
			ptr = ptr-&gt;left();
		}
		else
		{
			if (*ptr&lt;*node)
			{
				ptr=ptr-&gt;right();
			}
			else
			{
				if (*ptr==*node)
				{					
					return false;				
				}
			}
		}
	}</pre>
<pre>	node-&gt;setParent(dummy);</pre>
<pre>	if (dummy==NULL)
	{
		setRoot(node);		
	}
	else
	{
	//	node-&gt;setRoot(dummy-&gt;root());
		if (*dummy&gt;*node)
		{
			dummy-&gt;setLeft(node);
		}
		else
		{
			if (*dummy&lt;*node)
			{
				dummy-&gt;setRight(node);
			}
		}  //if &quot;== &quot;, donot insert;
	}
	return true;
}
				</pre>
<pre>void Tree::setLeft(Tree* leftSon)
{
	pLeft = leftSon;
}</pre>
<pre>void Tree::setRight(Tree* rightSon)
{
	pRight = rightSon;
}</pre>
<pre>void Tree::setParent(Tree* father)
{
	pParent = father;
}
</pre>
<pre>void Tree::giveBirth()
{
	Tree* leftTree = new Tree;
	Tree* rightTree = new Tree;
	char str[128];</pre>
<pre>	leftTree-&gt;setIndex(this-&gt;getIndex() *2 );
	rightTree-&gt;setIndex(this-&gt;getIndex() * 2 + 1);</pre>
<pre>	this-&gt;setLeft(leftTree);
	this-&gt;setRight(rightTree);</pre>
<pre>	leftTree-&gt;setParent(this);
	rightTree-&gt;setParent(this);</pre>
<pre>	strcpy(str, &quot;left son of &quot;);
	strcat(str, this-&gt;name());</pre>
<pre>	leftTree-&gt;setName(str);</pre>
<pre>	strcpy(str, &quot;right son of &quot;);
	strcat(str, this-&gt;name());</pre>
<pre>	rightTree-&gt;setName(str);</pre>
<pre>	leftTree-&gt;setParent(this);
	rightTree-&gt;setParent(this);</pre>
<pre>	if (root()==NULL)
	{
		setRoot(this);
		setParent(NULL);
	}
	/*
	else
	{
		leftTree-&gt;setRoot(root());
		rightTree-&gt;setRoot(root());
	}
	*/
}
</pre>
<pre>void Tree::setIndex(const int number)
{
	index = number;
}</pre>
<pre>const int Tree::getIndex()
{
	return index;
}</pre>
<pre>const char* Tree::name()
{
	return pName;
}</pre>
<pre>void Tree::setName(const char *str)
{
	if (str!=NULL)
	{
		pName = (char *)malloc(strlen(str)+1);
		strcpy(pName, str);
	}
}</pre>
<pre>Tree::Tree()
{
	setIndex(treeCounter);
	treeCounter++;
	pLeft = NULL;
	pRight = NULL;
	pParent = NULL;
	pName = NULL;
	pKey = NULL;
	freq = 0;
	rank =0;
}</pre>
<pre>Tree::~Tree()
{
	if (pName!=NULL)
	{
		free(pName);
	}
	if (pKey!=NULL)
	{
		free(pKey);
	}
}</pre>
<pre>Tree* Tree::left()
{
	return pLeft;
}</pre>
<pre>Tree* Tree::right()
{
	return pRight;
}</pre>
<pre>Tree* Tree::parent()
{
	return pParent;
}</pre>
<pre>BinaryTree* BinaryTree::next()
{
	Tree* result = NULL;</pre>
<pre>	if (right()!=NULL)
	{
		result = right();
		while (result-&gt;left!=NULL)
		{
			result = result-&gt;left();
		}
	}
	else
	{
		if (parent()!= NULL)
		{
			result = this;
			while(result-&gt;parent()!=NULL&amp;&amp;result==result-&gt;parent()-&gt;right())
			{
				result = result-&gt;parent();
			}
		}
		//result = null
	}
	return (BinaryTree*)result;
}</pre>
<pre>BinaryTree* BinaryTree::prev()
{
	Tree* result = NULL;
	if (left()!=NULL)
	{
		result = left();
		while (result-&gt;right()!=NULL)
		{
			result = result-&gt;right();
		}
	}
	else
	{
		if (parent()!=NULL)
		{
			result = this;
			while (result-&gt;parent()!=NULL&amp;&amp;result==result-&gt;parent()-&gt;left())
			{
				result = result-&gt;parent();
			}
		}
	}
	return (BinaryTree*)result;
}



<img border="0" src="picture/PowerDictionary.JPG" width="663" height="558">



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


</a>          


</p>

</body>

</html>
