<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> 
 Super Power Dictionary</b></font>     
</p>
</blockquote>
<div align="left">
  <pre><b><font color="#ff0000" size="5">C.Third Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is the third edition of my dictionary and it is very, very powerful now! Read in 20K words from a 2.3M text</b></pre>
</div>
<div align="left">
  <pre><b>file only uses less than 2seconds. However, ranking them will take 41seconds! As it need to track each node from</b></pre>
</div>
<div align="left">
  <pre><b>&quot;WordTree&quot; from &quot;big to small&quot; by &quot;Frequency&quot; and &quot;rank&quot; them by this sequence and then copy each node to a node</b></pre>
</div>
<div align="left">
  <pre><b>of &quot;RankTree&quot; then &quot;insert&quot; the new rankTree node into ranktree.</b></pre>
</div>
<div align="left">
  <pre><b>1¡£ Basic idea: I found out some mistakes in &quot;ranking&quot; functions. And it is really a hardtime to debug for a </b></pre>
</div>
<div align="left">
  <pre><b>whole day in lab(almost 8hours from 10:00AM to 18:30PM).</b></pre>
</div>
<div align="left">
  <pre><b>2¡£ Program design: </b><b>The biggest problem is still how to walk round the &quot;key&quot; problem of RankTree by using &quot;frequency&quot;</b></pre>
</div>
<div align="left">
  <pre><b>as key to compare and at same keep all ancester class with their original functions.</b>¡¡</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 traverse(...); </b></pre>
  <pre><b>	I add one more parameters to let &quot;RankTree Forest&quot; to start traversing from its own</b>  <b>&quot;root&quot;. 	</b></pre>
  <pre><b>	B. void insertRank(Tree* node, void* userPtr)</b></pre>
  <pre><b>	This is a special &quot;callback&quot; function to construct &quot;RankTree&quot; forest by &quot;traversing&quot; each node of</b></pre>
  <pre><b>	&quot;WordTree&quot;.</b></pre>
  <pre><b>	C. void Tree::maxWalk(...);</b></pre>
  <pre><b>	There are two format of this new MAXORDER way of traversing. Actually it is so-called &quot;from big to small&quot;</b></pre>
  <pre><b>	exactly opposite to &quot;MIDORDER&quot;.</b>¡¡</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. Still need improve.</b></pre>
  <pre><b>	C. Ranking counting and WordTree counting is differed by one, and I have not found the bug.</b></pre>
  <pre><b>	D. I hope I can rewrite the basic string-related part to enable the dictionary to read Chinese.</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 char* DefaultBackup = &quot;c:\\nickback.txt&quot;;
const MaxWordLength = 255;</pre>
<pre>enum TraverseOrder
{
	PREORDER, MIDORDER, POSTORDER, MAXORDER
};</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 maxWalk(Tree* node, void (*visit)(Tree* node));
	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 maxWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr);
	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:
	void decCount() {treeCounter --;}
	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, 
		Tree* start= root());
	void traverse(void (*visit)(Tree* node, void* userPtr), void* userPtr, 
		TraverseOrder defaultOrder = MIDORDER, Tree* start = root());
};
</pre>
<pre>void visitRank(Tree* node, void* userPtr);</pre>
<pre>void defaultVisit(Tree* node);</pre>
<pre>void insertRank(Tree* node, void* userPtr);</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, BinaryTree* start=(BinaryTree*)root());
	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);</pre>
<pre>public:
	WordTree* searchWord(WordTree* node, const char* buffer);
	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();
	virtual WordTree* findWord(const char* buffer);
};</pre>
<pre>class RankTree: public WordTree
{
private:
	</pre>
<pre>protected:
	</pre>
<pre>public:	
	virtual bool operator&gt;(Tree&amp; node);
	virtual bool operator&lt;(Tree&amp; node);
	void setRankTree(WordTree* wordRoot);
	RankTree();
	
</pre>
<pre>};

</pre>
<pre>int count=0;</pre>
<pre>int main()
{
	WordTree *ptr = new WordTree;
	char choice[6], fileName[30];
	long start =0;</pre>
<pre>	ptr = ptr-&gt;readFromFile(DefaultBackup);
	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)
			{
				start = time(0);
				ptr-&gt;openFile(fileName);
				cout&lt;&lt;&quot;\nTotal times spent for read file is:&quot;&lt;&lt;time(0) -start&lt;&lt;endl;
				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;\nThe total number of words in dictionary is:&quot;&lt;&lt;ptr-&gt;count()&lt;&lt;endl;
			cout&lt;&lt;&quot;\nDo you want to see contents?(yes or no)\n&quot;;
			</pre>
<pre>			
			</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)
			{
				start = time(0);
				int rankCount =0;
				RankTree *rankPtr = new RankTree;
				rankPtr-&gt;setFreq(ptr-&gt;getFreq());
				rankPtr-&gt;setName((char*)ptr-&gt;key());
				</pre>
<pre>				ptr-&gt;traverse(insertRank, (void*)rankPtr);</pre>
<pre>				rankPtr-&gt;traverse(visitRank, (void*)(&amp;rankCount), MAXORDER, rankPtr);
				cout&lt;&lt;&quot;\nTotal time for ranking is :&quot;&lt;&lt;time(0) - start&lt;&lt;endl;
				cout&lt;&lt;&quot;Do you want to see result of ranking?\n&quot;;
				cin&gt;&gt;choice;
				if (strcmp(choice, &quot;yes&quot;)==0)
				{
					rankPtr-&gt;traverse(defaultVisit, MAXORDER, rankPtr);
				}
				cout&lt;&lt;&quot;\nThe total number in ranktree is:&quot;&lt;&lt;rankPtr-&gt;count()&lt;&lt;endl;
			}
			cout&lt;&lt;&quot;The total number of words in dictionary is &quot;&lt;&lt;ptr-&gt;wordCount();
			ptr-&gt;saveToFile(DefaultBackup);
		}
	}</pre>
<pre>	return 0;
}
</pre>
<pre>int WordTree::wordCounter = 0;
int WordTree::wordLength = 20;
</pre>
<pre>void insertRank(Tree* node, void* userPtr)
{
	RankTree* rankPtr;// 
	rankPtr = (RankTree*)(((RankTree*)userPtr)-&gt;searchWord((RankTree*)userPtr,(char*)node-&gt;key()));
	if (rankPtr == NULL)
	{
		rankPtr = new RankTree;
		rankPtr-&gt;setName((char*)node-&gt;key());
		</pre>
<pre>		rankPtr-&gt;setFreq(node-&gt;getFreq());
		((RankTree*)(userPtr))-&gt;insert(rankPtr, (RankTree*)userPtr);
	}
}</pre>
<pre>RankTree::RankTree()
{
	decCount();
}</pre>
<pre>void visitRank(Tree* node, void* userPtr)
{
	node-&gt;setRank(*(int*)(userPtr));
	*(int*)(userPtr) +=1;
}
</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* 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)
{	
	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::maxWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{
		maxWalk(node-&gt;right(), visit);		
		visit(node);
		maxWalk(node-&gt;left(), visit);
		</pre>
<pre>	}
}</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::maxWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{
		maxWalk(node-&gt;right(), visit, userPtr);
		visit(node, userPtr);
		maxWalk(node-&gt;left(), visit, userPtr);		
	}
}
</pre>
<pre>void Tree::traverse(void (*visit)(Tree* node, void* userPtr), void* userPtr, 
		TraverseOrder defaultOrder, Tree* start)
{
	Tree *domino;
	domino = start;</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;
	case MAXORDER:
		maxWalk(domino, visit, userPtr);
		break;
	}
}

</pre>
<pre>void Tree::traverse(void (*visit)(Tree* node), TraverseOrder defaultOrder, Tree* start)
{
	Tree *domino;
	domino = start;</pre>
<pre>	switch(defaultOrder)
	{
	case PREORDER:
		preWalk(domino, visit);
		break;
	case MIDORDER:
		midWalk(domino, visit);
		break;
	case POSTORDER:
		postWalk(domino, visit);
		break;
	case MAXORDER:
		maxWalk(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, BinaryTree* start)
{
	Tree* ptr, *dummy;</pre>
<pre>	ptr = start;
	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/SuperDictionary.JPG" width="663" height="583"></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="Logic1.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="Sentence.htm"><img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</a>          


</p>

</body>

</html>
