一个应用二叉搜索树实现的字典,并存储结构于文件中

原创 2003年02月13日 10:01:00

                      Super Power Dictionary

This is the third edition of my dictionary and it is very, very powerful now! Read in 20K words from a 2.3M text
file only uses less than 2seconds. However, ranking them will take 41seconds! As it need to track each node from
"WordTree" from "big to small" by "Frequency" and "rank" them by this sequence and then copy each node to a node
of "RankTree" then "insert" the new rankTree node into ranktree.
1。 Basic idea: I found out some mistakes in "ranking" functions. And it is really a hardtime to debug for a 
whole day in lab(almost 8hours from 10:00AM to 18:30PM).
2。 Program design: The biggest problem is still how to walk round the "key" problem of RankTree by using "frequency"
as key to compare and at same keep all ancester class with their original functions. 
3。 Major function:
     A. void traverse(...); 
	I add one more parameters to let "RankTree Forest" to start traversing from its own  "root". 	
	B. void insertRank(Tree* node, void* userPtr)
	This is a special "callback" function to construct "RankTree" forest by "traversing" each node of
	"WordTree".
	C. void Tree::maxWalk(...);
	There are two format of this new MAXORDER way of traversing. Actually it is so-called "from big to small"
	exactly opposite to "MIDORDER". 
4。 Further improvement:
	A. I have to go soon, so, no more time.
	B. Still need improve.
	C. Ranking counting and WordTree counting is differed by one, and I have not found the bug.
	D. I hope I can rewrite the basic string-related part to enable the dictionary to read Chinese.
	
		
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <ctime>
using namespace std;
const char* DefaultBackup = "c://nickback.txt";
const MaxWordLength = 255;
enum TraverseOrder
{
	PREORDER, MIDORDER, POSTORDER, MAXORDER
};
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>(Tree&);
	virtual bool operator==(Tree&);
	virtual bool operator<(Tree&);	
	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());
};
void visitRank(Tree* node, void* userPtr);
void defaultVisit(Tree* node);
void insertRank(Tree* node, void* userPtr);
class BinaryTree: public Tree
{
private:
	
public:
	virtual void remove(BinaryTree* node);
	virtual BinaryTree* next();
	virtual BinaryTree* prev();
	virtual bool insert(BinaryTree* node, BinaryTree* start=(BinaryTree*)root());
	virtual ~BinaryTree();
};
class WordTree: public BinaryTree
{
private:
	static int wordLength;
	static int wordCounter;
	WordTree* addNode(WordTree* node, FILE** stream);
	
protected:
	void setWordCounter();
	void readWord(FILE** file);
	void addWord(char* buffer);
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>(Tree&);
	virtual bool operator==(Tree&);
	virtual bool operator<(Tree&);
	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);
};
class RankTree: public WordTree
{
private:
	
protected:
	
public:	
	virtual bool operator>(Tree& node);
	virtual bool operator<(Tree& node);
	void setRankTree(WordTree* wordRoot);
	RankTree();
	
};

int count=0;
int main()
{
	WordTree *ptr = new WordTree;
	char choice[6], fileName[30];
	long start =0;
	ptr = ptr->readFromFile(DefaultBackup);
	cout<<"quit? or input?/nEnter your choice: /n";
	cin>>choice;
	while (strcmp(choice, "quit")!=0&&strcmp(choice, "input")!=0)
	{
		cout<<"quit? or input?/n Enter your choic: /n";
		cin>>choice;
	}
	if (strcmp(choice, "quit")==0)
	{
		cout<<"The total number of words in dictionary is "<<ptr->wordCount()<<endl;
		return 0;
	}
	else
	{
		if (strcmp(choice, "input")==0)
		{
			cout<<"/nnow input file name here(input 'quit' to exit):/n";
			cin>>fileName;
			while (strcmp(fileName, "quit")!=0)
			{
				start = time(0);
				ptr->openFile(fileName);
				cout<<"/nTotal times spent for read file is:"<<time(0) -start<<endl;
				cout<<"/nnow input file name here(input quit to exit):/n";
				
				cin>>fileName;
			}
			cout<<"/nThe total number of words in dictionary is:"<<ptr->count()<<endl;
			cout<<"/nDo you want to see contents?(yes or no)/n";
			
			
			
			cin>>choice;
			if (strcmp(choice, "yes")==0)
			{
				ptr->traverse(defaultVisit, PREORDER);
			}
			cout<<"/nDo you want to rank the tree?(yes or no)/n";
			cin>>choice;
			if (strcmp(choice, "yes")==0)
			{
				start = time(0);
				int rankCount =0;
				RankTree *rankPtr = new RankTree;
				rankPtr->setFreq(ptr->getFreq());
				rankPtr->setName((char*)ptr->key());
				
				ptr->traverse(insertRank, (void*)rankPtr);
				rankPtr->traverse(visitRank, (void*)(&rankCount), MAXORDER, rankPtr);
				cout<<"/nTotal time for ranking is :"<<time(0) - start<<endl;
				cout<<"Do you want to see result of ranking?/n";
				cin>>choice;
				if (strcmp(choice, "yes")==0)
				{
					rankPtr->traverse(defaultVisit, MAXORDER, rankPtr);
				}
				cout<<"/nThe total number in ranktree is:"<<rankPtr->count()<<endl;
			}
			cout<<"The total number of words in dictionary is "<<ptr->wordCount();
			ptr->saveToFile(DefaultBackup);
		}
	}
	return 0;
}
int WordTree::wordCounter = 0;
int WordTree::wordLength = 20;
void insertRank(Tree* node, void* userPtr)
{
	RankTree* rankPtr;// 
	rankPtr = (RankTree*)(((RankTree*)userPtr)->searchWord((RankTree*)userPtr,(char*)node->key()));
	if (rankPtr == NULL)
	{
		rankPtr = new RankTree;
		rankPtr->setName((char*)node->key());
		
		rankPtr->setFreq(node->getFreq());
		((RankTree*)(userPtr))->insert(rankPtr, (RankTree*)userPtr);
	}
}
RankTree::RankTree()
{
	decCount();
}
void visitRank(Tree* node, void* userPtr)
{
	node->setRank(*(int*)(userPtr));
	*(int*)(userPtr) +=1;
}
bool RankTree::operator <(Tree& node)
{
	int result;
	result = getFreq() - node.getFreq();
	if (result !=0)
	{
		return (result<0);
	}
	else
	{
		return (strcmp((char*)key(), (char*)node.key())<0);
	}
}
bool RankTree::operator >(Tree& node)
{
	int result;
	result = getFreq() - node.getFreq();
	if (result !=0)
	{
		return (result>0);
	}
	else
	{
		return (strcmp((char*)key(), (char*)node.key())>0);
	}
}
void RankTree::setRankTree(WordTree* wordRoot)
{
	RankTree* ptr;
	if (wordRoot!=NULL)
	{
		if (this->root()!=NULL)
		{
			ptr = new RankTree;
			ptr->setFreq(wordRoot->getFreq());
			ptr->setKey((void*)wordRoot->key());
			ptr->insert(ptr);
		}
		else
		{
			this->setRoot(this);
			this->setFreq(wordRoot->getFreq());
			this->setKey((void*)wordRoot->key());
		}
		setRankTree((WordTree*)wordRoot->left());
		setRankTree((WordTree*)wordRoot->right());
	}
}
BinaryTree::~BinaryTree()
{
}
WordTree::~WordTree()
{
	
}
void WordTree::setWordCounter()
{
	wordCounter ++;
}
const int WordTree::getWordLength()
{
	return wordLength;
}
WordTree* WordTree::addNode(WordTree* node, FILE** stream)
{
	char buffer[MaxWordLength];
	int index, pIndex, number;
	WordTree *domino;
	char *ptr=buffer, ch;
	
	fread((void*)(&index), sizeof(int), 1, *stream);
	fread((void*)(&pIndex), sizeof(int), 1, *stream);
	if (index==-1&&pIndex==-1)
	{
		return NULL;
	}
	do
	{
		ch = fgetc(*stream);
		*ptr = ch;
		ptr++;
	}
	while(ch!='/0');
	fread((void*)(&number), sizeof(int), 1, *stream);
	setWordCounter();  //add a word
	if (pIndex== -1)  //this is root
	{			
		node->setIndex(index);
		node->setFreq(number);
		node->setName(buffer);
		node->setRoot(node);
		return node;
	}
	while (pIndex!=node->getIndex())
	{	
		if (node->parent()==NULL)
		{
			return NULL;
		}
		node= (WordTree*)node->parent(); 
	}
	if (node!=NULL&&pIndex==node->getIndex())
	{
		domino = new WordTree;
		domino->setIndex(index);
		domino->setName(buffer);
		domino->setFreq(number);
		domino->setParent(node);
		if (*domino<*node)
		{
			node->setLeft(domino);
		}
		else
		{
			node->setRight(domino);
		}
		
		return domino;
	}
	else
	{
		return NULL;
	}
}
WordTree* WordTree::readNode(WordTree* node, FILE** stream)
{	
	WordTree* domino = node;
	while (domino!=NULL)
	{
		domino = addNode(domino, stream);
	}
	return (WordTree*)node->root();  //this is ugly as I have to remove those sentinal 
}
WordTree* WordTree::readFromFile(const char* fileName)
{
	FILE* stream;
	if ((stream=fopen(fileName, "r+b"))==NULL)
	{
		cout<<"unable to open file "<<fileName<<endl;
		return NULL;
	}
	else
	{
		WordTree* ptr= new WordTree;
		return readNode(ptr, &stream);	
	}
	fclose(stream);
}
void WordTree::saveNode(WordTree* node, FILE** stream)
{
	int first, second, number;
	first = node->getIndex();
	number = getFreq();
	fwrite((void*)(&first), sizeof(int), 1, *stream);
	if (node->parent()==NULL)
	{
		second = -1;		
	}
	else
	{
		second = node->parent()->getIndex();		
	}
	fwrite((void*)(&second), sizeof(int), 1, *stream);
	fwrite((void*)(node->name()),sizeof(char), strlen(node->name()), *stream);
	fputc('/0', *stream);//I have to put this '/n' otherwise there is always problem!
	fwrite((void*)(&number), sizeof(int), 1, *stream);
}
	
void traverseTree(WordTree* node, FILE** stream)
{
	if (node!=NULL)
	{
		node->saveNode(node, stream);
		traverseTree((WordTree*)node->left(), stream);
		traverseTree((WordTree*)node->right(), stream);
	}
}
void writeEnd(FILE** stream)
{
	int temp1=-1, temp2=-1;
	fwrite((void*)(&temp1), sizeof(int), 1, *stream);
	fwrite((void*)(&temp2), sizeof(int), 1, *stream);
}
void WordTree::saveToFile(const char* fileName)
{
	void traverseTree(WordTree* node, FILE ** stream);
	void writeEnd(FILE** stream);
	WordTree *domino;
	
	FILE * stream;
	
	if ((stream=fopen("c://nickback.txt", "w+b"))==NULL)
	{
		cout<<"unable to save to file "<<fileName<<endl;
	}
	else
	{
		domino = (WordTree*)root();
		traverseTree((WordTree*)domino, &stream);
	}
	writeEnd(&stream);
	fclose(stream);
}
	
const int Tree::count()
{
	return treeCounter;
}
void WordTree::setWordLength(const int newLength)
{
	if (newLength>MaxWordLength)
	{
		cout<<"exceed max word length."<<endl;
	}
	else
	{
		wordLength = newLength;
	}
}
int WordTree::compare(const void*otherKey)
{
	return strcmp((char*)key(), (char*)otherKey);
}
int WordTree::wordCount()
{
	return wordCounter;
}
WordTree::WordTree()
{
	
}
void WordTree::openFile(const char* fileName)
{
	FILE * stream;	
	if ((stream=fopen(fileName, "r+b"))==NULL)
	{
		cout<<"unable open file!"<<endl;
	}
	else
	{
		readWord(&stream);
	}
	fclose(stream);
}
void WordTree::readWord(FILE **stream)
{
	char buffer[MaxWordLength];
	char *ptr = buffer;
	char ch;
	int counter =0;
	
	while (!feof(*stream))
	{
		ptr = buffer;
		counter =  0;
		ch = toupper(fgetc(*stream));
		while (isalnum(ch)&&!feof(*stream)&&counter<wordLength)
		{
			*ptr = ch;
			ch = toupper(fgetc(*stream));
			ptr++;
			counter++;
		}
		if (ptr!=buffer)
		{
			*ptr='/0';
			addWord(buffer);
		}	
	}
}
WordTree* WordTree::searchWord(WordTree* node, const char* buffer)
{
	int result;
	if (node!=NULL)
	{		
		result = strcmp((char*)(node->key()), buffer);
		if (result ==0)
		{
			return node;
		}
		else
		{
			if (result < 0)
			{
				return searchWord((WordTree*)node->right(), buffer);
			}
			else
			{
				return searchWord((WordTree*)node->left(), buffer);
			}
		}
	}
	else
	{
		return NULL;
	}
}
WordTree* WordTree::findWord(const char *buffer)
{	
	return searchWord((WordTree*)root(), buffer);
}
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;
	
		ptr->setName(buffer);    
		if (ptr->insert(ptr))
		{
			setWordCounter();
		}	
	}
	else
	{
		ptr->setFreq();
	}
}
void WordTree::setName(const char *str)
{
	Tree::setName(str);
	setKey((void*)name());
}
int Tree::treeCounter= 0;
WordTree::WordTree(const char* fileName)
{
	WordTree::WordTree();
	openFile(fileName);
}
void WordTree::setKey(void * newKey)
{
	pKey = newKey;
}
bool WordTree::operator <(Tree& second)
{
	if (strcmp((char*)key(), (char*)second.key())<0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool WordTree::operator ==(Tree& second)
{
	if (strcmp((char*)key(), (char*)second.key())==0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
bool WordTree::operator >(Tree& second)
{
	if (strcmp((char*)key(), (char*)second.key())>0)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void defaultVisit(Tree* node)
{
	cout<<"/n/n";
	cout<<"default visiting tree index:"<<node->getIndex()<<endl;
	cout<<"and tree name is:"<<node->name()<<endl;
	cout<<"and its frequency is: "<<(node)->getFreq()<<endl;
	cout<<"and its rank is:"<<node->getRank()<<endl;
	if (node->parent()!=NULL)
	{
		cout<<"its parent is:"<<node->parent()->name()<<endl;
		if (node==node->parent()->left())
		{
			cout<<"and it is left son."<<endl;
		}
		else
		{
			cout<<"and it is right son"<<endl;
		}
	}
	else
	{
		cout<<"it has no parent"<<endl;
	}
	cout<<"/n/n";
}
void Tree::preWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{	
		visit(node);
		preWalk(node->left(), visit);		
		preWalk(node->right(), visit);
	}
}

void Tree::postWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{
		postWalk(node->left(), visit);
		postWalk(node->right(), visit);
		visit(node);
	}
}
void Tree::maxWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{
		maxWalk(node->right(), visit);		
		visit(node);
		maxWalk(node->left(), visit);
		
	}
}
void Tree::midWalk(Tree* node, void (*visit)(Tree* node))
{
	if (node!=NULL)
	{
		midWalk(node->left(), visit);
		visit(node);
		midWalk(node->right(), visit);
	}
}
void Tree::preWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{	
		visit(node, userPtr);
		preWalk(node->left(), visit, userPtr);		
		preWalk(node->right(), visit, userPtr);
	}
}
void Tree::midWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{
		midWalk(node->left(), visit, userPtr);
		visit(node, userPtr);
		midWalk(node->right(), visit, userPtr);
	}
}
void Tree::postWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{
		postWalk(node->left(), visit, userPtr);
		postWalk(node->right(), visit, userPtr);
		visit(node, userPtr);
	}
}
void Tree::maxWalk(Tree* node, void (*visit)(Tree* node, void* userPtr), void* userPtr)
{
	if (node!=NULL)
	{
		maxWalk(node->right(), visit, userPtr);
		visit(node, userPtr);
		maxWalk(node->left(), visit, userPtr);		
	}
}
void Tree::traverse(void (*visit)(Tree* node, void* userPtr), void* userPtr, 
		TraverseOrder defaultOrder, Tree* start)
{
	Tree *domino;
	domino = start;
	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;
	}
}

void Tree::traverse(void (*visit)(Tree* node), TraverseOrder defaultOrder, Tree* start)
{
	Tree *domino;
	domino = start;
	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;
	}
}
Tree* Tree::pRoot = NULL;
void BinaryTree::remove(BinaryTree* node)
{
	BinaryTree* ptr=NULL;
	if (node->left()==NULL || node->right()==NULL)
	{
		if (node->left()!=NULL)
		{
			node->parent()->setLeft(node->left());
			node->left()->setParent(node->parent());
		}
		if (node->right()!=NULL)
		{
			node->parent()->setRight(node->right());
			node->right()->setParent(node->parent());
		}
	}
	else
	{
		ptr = node->next();
		remove(ptr);
		ptr->setParent(node->parent());
		if (node->parent()==NULL)
		{
			node->setRoot(ptr);			
		}
		else
		{
			if (node==node->parent()->left())
			{
				node->parent()->setLeft(ptr);
			}
			else
			{
				node->parent()->setRight(ptr);
			}
			ptr->setLeft(node->left());
			ptr->setRight(node->right());
		}
	}
}
bool Tree::operator==(Tree& second)
{
	if (this->compare(second.key())==0)
	{
		return true;
	}
	else
	{
		return false;
	}	
}
bool Tree::operator <(Tree& second)
{
	if (this->compare(second.key())<0)
	{
		return true;
	}
	else
	{
		return false;
	}	
}
bool Tree::operator >(Tree& second)
{
	if (this->compare(second.key())>0)
	{
		return true;
	}
	else
	{
		return false;
	}	
}
int Tree::compare(const void * otherKey)
{
	return *((int*)(key()))- *((int*)(otherKey));
}
void* Tree::key()
{
	return pKey;
}
void Tree::setKey(void *newKey)
{
	pKey = malloc(sizeof(int));
	*(int*)(pKey) = *(int*)(newKey);
}

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



                                                         back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)

http://www3.sympatico.ca/qingzhehuang/SuperDictionary.htm

一个应用二叉搜索树实现的字典,并存储结构于文件中 选择自 nickhuang2002 的 Blog

                        Super Power Dictionary C.Third EditionThis is the third edition of my dictio...
  • coolfiry
  • coolfiry
  • 2006年07月14日 15:58
  • 641

二叉搜索树实现简单字典

日常生活中我们经常使用字典来查找单词的中文意思,也会根据中文来查找所对应的汉语。前面我们知道二叉树实现可以迅速查找一个数据,而且可以插入和删除。 这里我们可以用搜索二叉树实现简单的字典,查找英文单词...
  • f2016913
  • f2016913
  • 2017年04月04日 09:52
  • 661

数据结构(22)--动态查找之二叉排序树(二叉查找树)

参考书籍:数据结构(C语言版)严蔚敏吴伟民编著清华大学出版社 1.动态查找表 特点:表结构在查找过程中动态生成。 要求:对于给定值 key, 若表中存在其关键字等于 key的记录,则查找成功返回,并且...
  • u010366748
  • u010366748
  • 2016年03月07日 18:23
  • 947

二叉查找树C++实现

二叉排序树(Binary Sort Tree)又称二叉查找树,它的特点是: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根...
  • weiwenhp
  • weiwenhp
  • 2013年03月06日 11:56
  • 4519

Python中基本数据存储结构列表、元组和字典

在Python的学习中我们看到Python有列表、元组和字典三种基本的数据存储结构,下面对着三种结构做一个总结1. 列表(list)列表在Python中是一个任意类型对象位置的相关有序集合,它没有固定...
  • keith_bb
  • keith_bb
  • 2017年04月09日 12:45
  • 1682

二叉查找树的C++实现

二叉查找树的插入和删除详解请看:http://blog.csdn.net/sysu_arui/article/details/7865864 前面详细讲解了二叉查找树插入和删除,现在给出完整的C++...
  • sysu_arui
  • sysu_arui
  • 2012年08月21日 18:11
  • 2225

Orcale多个字典ID保存在一个字段

Oracle分割列内容转换为多条数据
  • wupd2014
  • wupd2014
  • 2017年03月13日 11:38
  • 186

二叉搜索树的应用

如果给我一个二叉搜索树的数据,一定要从头开始找,另外我还学到了双指针或多个指针记录前面顺序等想法。毕竟没学过ACM,啥都不会,哈哈哈哈#include #include using namespac...
  • liuzhustu
  • liuzhustu
  • 2016年11月18日 14:28
  • 1015

iOS面试题【附部分答案】

问答题: 1.      两段代码共存于一个文件,编译时有选择的编译其中的一部分,请问如何实现? 答案:条件预编译:#if        #ifdef  #ifndef                ...
  • yewave133
  • yewave133
  • 2016年07月03日 22:55
  • 454

动态规划--4.最优二叉查找树

1.最优二叉查找树 (1)左孩子 (2)树内关键字k1...kn(中间节点k1 d0,d1,dn ;d0表示小于k1的所有值, dn表示大于kn的所有值,它们对应的搜索概率是 q0,q1...q...
  • u012813201
  • u012813201
  • 2017年03月15日 10:17
  • 134
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个应用二叉搜索树实现的字典,并存储结构于文件中
举报原因:
原因补充:

(最多只允许输入30个字)