C++ツリーの構築、前/中/後の再帰/非再帰実装

5494 ワード

//BinNode.h

#ifndef BINNODE_H
#define BINNODE_H

class BinNode 
{
public:
	BinNode():data(0),lchild(0),rchild(0){};
	BinNode *lchild,*rchild;
	char *data;
};

#endif
//BinTree.h

#ifndef BINTREE_H
#define BINTREE_H

#include "BinNode.h"
#include <stack>
using std::stack;

class BinTree
{
public:
	BinTree(int num);
	void InsertNode(char *);
	void PreOrderTraverse(void(*fun)(BinNode&));//         
	void InOrderTraverse(void(*fun)(BinNode&));//         
	void PostOrderTraverse(void(*fun)(BinNode&));//         

	void PreOrder(void(*fun)(BinNode&));//          
	void InOrder(void(*fun)(BinNode&));//          
	void PostOrder(void(*fun)(BinNode&));//          
	~BinTree(){delete HEAD;}
	BinNode *HEAD;
	int NumOfNodes;
private:
	void PreOrderTraverse(void(*fun)(BinNode&),BinNode *);
	void InOrderTraverse(void(*fun)(BinNode&),BinNode *);
	void PostOrderTraverse(void(*fun)(BinNode&),BinNode *);
	void LevelOrderTraverse(void(*fun)(BinNode&),BinNode *);
	int MAX_NUM;
	stack<BinNode> s;
};



#endif
//BinTree.cpp

#include <cstring>
#include "BinTree.h"


BinTree::BinTree(int num)
{
	MAX_NUM = num;
	NumOfNodes = 0;
	HEAD = 0;
}

void BinTree::InsertNode(char *to_data)
{
	BinNode *temp = HEAD,*pre;
	while(temp)
	{
		if(strcmp(to_data,temp->data) == 0)return;
		pre = temp;
		if(strcmp(to_data,temp->data) > 0)
			temp = temp->rchild;
		else
			temp = temp->lchild;
	}
	BinNode *to_node = new BinNode;
	to_node->data = to_data;

	if(0 == HEAD)
	{
		HEAD = to_node;
		NumOfNodes ++;
	}
	else
	{
		if(strcmp(to_data,pre->data) > 0)pre->rchild = to_node;
		else pre->lchild = to_node;
		NumOfNodes ++;
	}
}

void BinTree::DeleteNode(BinNode &to_delete)//    
{
	BinNode *temp = HEAD;
	while(temp)
	{
		if(strcmp(temp->data,to_delete.data) > 0)
			temp = temp->lchild;
		if(strcmp(temp->data,to_delete.data) < 0)
			temp = temp->rchild;
		if(strcmp(temp->data,to_delete.data) == 0)
			break;
	}

	if(0 == temp)return;
}

void BinTree::PreOrderTraverse(void (*fun)(BinNode &),BinNode *top)
{
	BinNode *temp = top;
	if(temp)
	{
		fun(*temp);
		PreOrderTraverse(fun,temp->lchild);
		PreOrderTraverse(fun,temp->rchild);
	}
}

void BinTree::PreOrderTraverse(void(*fun)(BinNode&))
{
	PreOrderTraverse(fun,HEAD);
}

void BinTree::InOrderTraverse(void (*fun)(BinNode &), BinNode *top)
{
	BinNode *temp = top;
	if(temp)
	{
		InOrderTraverse(fun,temp->lchild);
		fun(*temp);
		InOrderTraverse(fun,temp->rchild);
	}
}

void BinTree::InOrderTraverse(void(*fun)(BinNode&))
{
	InOrderTraverse(fun,HEAD);
}

void BinTree::PostOrderTraverse(void (*fun)(BinNode &), BinNode *top)
{
	BinNode *temp = top;
	if(temp)
	{
		PostOrderTraverse(fun,temp->lchild);
		PostOrderTraverse(fun,temp->rchild);
		fun(*temp);
	}
}

void BinTree::PostOrderTraverse(void(*fun)(BinNode&))
{
	PostOrderTraverse(fun,HEAD);
}

void BinTree::PreOrder(void(*fun)(BinNode&))
{
	BinNode *temp = HEAD;
	while(temp || !(s.empty()))
	{
		if(temp)
		{
			s.push(*temp);
			fun(*temp);
			temp = temp->lchild;
		}
		else
		{
			temp = &(s.top());
			s.pop();
			temp = temp->rchild;
		}
	}
}

void BinTree::InOrder(void(*fun)(BinNode&))
{
	BinNode *temp = HEAD;
	while(temp || !(s.empty()))
	{
		if(temp)
		{
			s.push(*temp);
			temp = temp->lchild;
		}
		else
		{
			temp = &(s.top());
			fun(*temp);
			s.pop();
			temp = temp->rchild;
		}
	}
}

void BinTree::PostOrder(void(*fun)(BinNode&))
{
	BinNode *temp = HEAD;
	BinNode *pre;
	while(temp || !s.empty())
	{
		if(temp)
		{
			s.push(*temp);
			temp = temp->lchild;
		}
		else
		{
			temp = &(s.top());
			if(temp->rchild && (temp->rchild->data != pre->data))
			{
				temp = temp->rchild;
				s.push(*temp);
				temp = temp->lchild;
			}
			else
			{
				temp = &(s.top());
				fun(*temp);
				s.pop();
				pre = temp;
				temp = 0;
			}
		}
	}
}
//driver.cpp

#include <iostream>
#include <string>
using namespace std;

#include "BinNode.h"
#include "BinTree.h"

const int MAX_NUM = 100;

void myfun(BinNode& BN)
{
	cout<<BN.data<<endl;
}

int main()
{
	BinTree *BT = new BinTree(MAX_NUM);

	BinNode node_to2;
	node_to2.data = "Another test program.";
	BT->InsertNode(node_to2.data);

	BinNode node_to;
	node_to.data = "This is a test program.";
	BT->InsertNode(node_to.data);

	BinNode node_to3;
	node_to3.data = "Ahahahahahahahah";
	BT->InsertNode(node_to3.data);
	
	cout<<"----------------PreOrderTraverse-----------------"<<endl;
	BT->PreOrderTraverse(myfun);
	cout<<"----------------InOrderTraverse------------------"<<endl;
	BT->InOrderTraverse(myfun);
	cout<<"----------------PostOrderTraverse----------------"<<endl;
	BT->PostOrderTraverse(myfun);
	cout<<"---------------------InOrder---------------------"<<endl;
	BT->InOrder(myfun);
	cout<<"---------------------PreOrder--------------------"<<endl;
	BT->PreOrder(myfun);
	cout<<"---------------------PostOrder-------------------"<<endl;
	BT->PostOrder(myfun);
//	cout<<BT->NumOfNodes<<endl;
	return 0;
}