//二叉树类的异常处理类
#ifndef TREE_EXCEPTION_H_
#define TREE_EXCEPTION_H_
#include<stdexcept>
#include<string>
class TreeException :public std::logic_error
{
public:
TreeException(const std::string &message="")
:std::logic_error(message.c_str())
{}
};
#endif
//二叉树的头文件
#ifndef BINARY_TREE_H_
#define BINARY_TREE_H_
#include"tree_exception.h"
#include<string>
typedef std::string ItemType;
typedef void (*FuncType)(ItemType &_item);
class BinaryTree
{
public:
//constructor and destructor
BinaryTree();
BinaryTree(const ItemType &rootitem);
BinaryTree(const BinaryTree &tree);
BinaryTree(const ItemType &rootitem,
BinaryTree &leftTree,
BinaryTree &rightTree);
virtual ~BinaryTree();
//binary tree operations
virtual bool empty()const;
virtual ItemType getRootData()const
throw(TreeException);
virtual void setRootData(ItemType rootitem)
throw(TreeException);
virtual void attachLeft(const ItemType &_item)
throw(TreeException);
virtual void attachRight(const ItemType &_item)
throw(TreeException);
virtual void attachLeftSubtree(BinaryTree &tree)
throw(TreeException);
virtual void attachRightSubtree(BinaryTree &tree)
throw(TreeException);
virtual void deleteLeftSubtree(BinaryTree &tree)
throw(TreeException);
virtual void deleteRightSubtree(BinaryTree &tree)
throw(TreeException);
virtual BinaryTree getLeftSubtree()const
throw(TreeException);
virtual BinaryTree getRightSubtree()const
throw(TreeException);
virtual void preorderTraverse(FuncType visit);
virtual void inorderTraverse(FuncType visit);
virtual void postorderTraverse(FuncType visit);
virtual BinaryTree &operator=(const BinaryTree &rhs);
protected:
struct TreeNode
{
TreeNode();
TreeNode(const ItemType &_item,
TreeNode *left=NULL,
TreeNode *right=NULL)
:item(_item),leftPtr(left),rightPtr(right)
{}
ItemType item;
TreeNode *leftPtr;
TreeNode *rightPtr;
};
BinaryTree(TreeNode *nodePtr);
void copyTree(TreeNode *treePtr,TreeNode *&newTreePtr)const
throw(TreeException);
void destroyTree(TreeNode *&treePtr);
TreeNode *&rootPtr();
void setRootPtr(TreeNode *newRoot);
TreeNode *& getLeftPtr(TreeNode *&nodePtr);
TreeNode *& getRightPtr(TreeNode *&nodePtr);
void setChildPtr(TreeNode *nodePtr,
TreeNode *&leftChildPtr,
TreeNode *&rightChildPtr);
void preorder(TreeNode *treePtr,FuncType visit);
void inorder(TreeNode *treePtr,FuncType visit);
void postorder(TreeNode *treePtr,FuncType visit);
private:
TreeNode *root;
};
#endif
//二叉树的实现文件
#include"binary_tree.h"
#include<cstddef>
#include<cassert>
BinaryTree::BinaryTree():root(NULL)
{
}
BinaryTree::BinaryTree(const ItemType &rootitem)
{
root=new TreeNode(rootitem,NULL,NULL);
assert(root!=NULL);
}
BinaryTree::BinaryTree(const BinaryTree &tree)
{
copyTree(tree.root,root);
}
BinaryTree::BinaryTree(const ItemType &rootitem,
BinaryTree &leftTree,
BinaryTree &rightTree)
{
root =new TreeNode(rootitem,NULL,NULL);
assert(root!=NULL);
attachLeftSubtree(leftTree);
attachRightSubtree(rightTree);
}
BinaryTree::BinaryTree(TreeNode *nodePtr)
{
copyTree(nodePtr,root);
}
BinaryTree::~BinaryTree()
{
destroyTree(root);
}
bool BinaryTree::empty()const
{
return(root==NULL);
}
ItemType BinaryTree::getRootData()const
throw(TreeException)
{
if(empty())
throw TreeException("calling getRootData function failed :empty tree");
return root->item;
}
void BinaryTree::setRootData(ItemType rootitem)
throw(TreeException)
{
if(empty())
{
root=new TreeNode(rootitem,NULL,NULL);
if(root==NULL)
throw TreeException("calling setRootData function failed :allocate memory failed ");
}
else
root->item=rootitem;
}
void BinaryTree::attachLeft(const ItemType &_item)
throw(TreeException)
{
if(empty())
throw TreeException("calling attachLeft function failed:empty tree ");
else if(root->leftPtr!=NULL)
throw TreeException("calling attachLeft function failed :tree's left child existed ");
else
{
root->leftPtr=new TreeNode(_item,NULL,NULL);
if(root->leftPtr==NULL)
throw TreeException("calling attachLeft function failed :allocate memory failed ");
}
}
void BinaryTree::attachRight(const ItemType &_item)
throw(TreeException)
{
if(empty())
throw TreeException("calling attachRight function failed :empty tree");
else if(root->rightPtr!=NULL)
throw TreeException("calling attachRight function failed :tree's right child existed ");
else
{
root->rightPtr=new TreeNode(_item,NULL,NULL);
if(root->rightPtr==NULL)
throw TreeException("calling attachRight function failed :allocate memory failed ");
}
}
void BinaryTree::attachLeftSubtree( BinaryTree &tree)
throw(TreeException)
{
if(empty())
throw TreeException("calling attachLeftSubtree function failed :tree is empty ");
else if(root->leftPtr!=NULL)
throw TreeException("calling attachLeftSubtree function failed :tree's right child existed ");
else
{ root->leftPtr=tree.root;
tree.root=NULL;
}
}
void BinaryTree::attachRightSubtree(BinaryTree &tree)
throw(TreeException)
{
if(empty())
throw TreeException("calling attachRightSubtree function failed :empty tree ");
else if(root->rightPtr!=NULL)
throw TreeException("calling attachRightSubtree function failed :tree's right child existed ");
else{
root->rightPtr=tree.root;
tree.root=NULL;
}
}
void BinaryTree::deleteLeftSubtree(BinaryTree &tree)throw(TreeException)
{
if(empty())
throw TreeException("calling deleteLeftSubtree function failed :emtpy tree");
else
{
tree=BinaryTree(root->leftPtr);
root->leftPtr=NULL;
}
}
void BinaryTree::deleteRightSubtree(BinaryTree &tree)
throw(TreeException)
{
if(empty())
throw TreeException("calling deleteRightSubtree function failed :empty tree ");
else
{
tree=BinaryTree(root->rightPtr);
root->rightPtr=NULL;
}
}
BinaryTree &BinaryTree::operator=(const BinaryTree &rhs)
{
if(this==&rhs)
return *this;
else
{
destroyTree(root);
copyTree(rhs.root,root);
return *this;
}
}
BinaryTree BinaryTree::getLeftSubtree()const
throw(TreeException)
{
if(empty())
throw TreeException("calling getleftSubtree function failed:empty tree ");
else
{
return BinaryTree(root->leftPtr);
}
}
BinaryTree BinaryTree::getRightSubtree()const
throw(TreeException)
{
if(empty())
throw TreeException("calling getrightSubtree function failed :empty tree ");
else
return BinaryTree(root->rightPtr);
}
void BinaryTree::preorderTraverse(FuncType visit)
{
preorder(root,visit);
}
void BinaryTree::inorderTraverse(FuncType visit)
{
inorder(root,visit);
}
void BinaryTree::postorderTraverse(FuncType visit)
{
postorder(root,visit);
}
void BinaryTree::copyTree(TreeNode *treePtr,TreeNode *&newTreePtr)const
throw(TreeException)
{
if(treePtr!=NULL)
{
newTreePtr =new TreeNode(treePtr->item,NULL,NULL);
if(newTreePtr==NULL)
throw TreeException("calling copyTree function failed :allocate memory faild ");
copyTree(treePtr->leftPtr,newTreePtr->leftPtr);
copyTree(treePtr->rightPtr,newTreePtr->rightPtr);
}
else
newTreePtr=NULL;
}
void BinaryTree::destroyTree(TreeNode *&treePtr)
{
if(treePtr!=NULL)
{
destroyTree(treePtr->leftPtr);
destroyTree(treePtr->rightPtr);
delete treePtr;
treePtr=NULL;
}
}
BinaryTree::TreeNode *& BinaryTree::rootPtr()
{
return root;
}
void BinaryTree::setRootPtr(TreeNode *newRoot)
{
destroyTree(root);
root=newRoot;
}
void BinaryTree::setChildPtr(TreeNode *nodePtr,
TreeNode *&leftChildPtr,
TreeNode *&rightChildPtr)
{
destroyTree(nodePtr->leftPtr);
destroyTree(nodePtr->rightPtr);
nodePtr->leftPtr=leftChildPtr;
nodePtr->rightPtr=rightChildPtr;
}
BinaryTree::TreeNode *&BinaryTree::getLeftPtr(TreeNode *&nodePtr)
{
return nodePtr->leftPtr;
}
BinaryTree::TreeNode *&BinaryTree::getRightPtr(TreeNode *&nodePtr)
{
return nodePtr->rightPtr;
}
void BinaryTree::preorder(TreeNode *treePtr,FuncType visit)
{
if(treePtr!=NULL)
{
visit(treePtr->item);
preorder(treePtr->leftPtr,visit);
preorder(treePtr->rightPtr,visit);
}
}
void BinaryTree::inorder(TreeNode *treePtr,FuncType visit)
{
if(treePtr!=NULL)
{
inorder(treePtr->leftPtr,visit);
visit(treePtr->item);
inorder(treePtr->rightPtr,visit);
}
}
void BinaryTree::postorder(TreeNode *treePtr,FuncType visit)
{
if(treePtr!=NULL)
{
postorder(treePtr->leftPtr,visit);
postorder(treePtr->rightPtr,visit);
visit(treePtr->item);
}
}