templateclass BinaryTree;
templateclass BiTreeNode
{
friend class BinaryTree;
public:
T data;//数据域
BiTreeNode() :leftChild(NULL), rightChild(NULL) {}//构造函数
BiTreeNode(T item,BiTreeNode*left=NULL,BiTreeNode*right=NULL)//构造函数
:data(item),leftChild(left),rightChild(right){}
~BiTreeNode(){}//析构函数
BiTreeNode*& Left()
{//获得左孩子
return leftChild;
}
BiTreeNode*& Right()
{//获得右孩子
return rightChild;
}
private:
BiTreeNode* leftChild;//左子树指针
BiTreeNode* rightChild;//右子树指针
};
templateclass BinaryTree
{
public:
BinaryTree() :root(NULL){};//构造函数
~BinaryTree() {};//析构函数
//构造二叉树
void MakeTree(const T& item);
//第一类操作的成员函数
bool Root();//使根结点为当前结点
bool Parent();//使双亲结点为当前结点
bool LeftChild();//使左孩子结点为当前结点
bool RightChild();//使右孩子结点为当前结点
//第二类操作的成员函数
void InsertChild(const T &value);//使根结点为当前结点
void DeleteSubTree(BiTreeNode*& t);//删除以t为根结点的子树
void clear();//清空树
//第三类操作的成员函数
//遍历访问二叉树
void PreOrder(void(*visit)(T item));//前序遍历访问树
void InOrder(void(*visit)(T item));//中序遍历访问树
void PostOrder(void(*visit)(T item));//后序遍历访问树
private:
BiTreeNode* root;//根结点指针
BiTreeNode* current;//当前结点指针
bool Current(BiTreeNode*& t);//使当前结点为t所指结点
void PreOrder(BiTreeNode*& t, void(*visit)(T item));
void InOrder(BiTreeNode*& t, void(*visit)(T item));
void PostOrder(BiTreeNode*& t, void(*visit)(T item));
//插入
void Insert(const T& value, BiTreeNode*& t);
//在树root中回溯查找s的双亲结点
BiTreeNode* SearchParent(BiTreeNode*& root, BiTreeNode*& s);
};
即DLR,也叫做先根遍历、先序遍历、前序周游,记作根左右。前序遍历首先访问根结点,然后遍历左子树,最后遍历右子树。
这里使用visit(item)
函数来输出结点数据域值,同时,visit(item)
函数经过修改之后,也可以输出自定义数据类型中需要输出的数据。
visit(item)
函数的实现如下:
template
void Visit(T item)
{
cout << item << " ";
}
template
inline void BinaryTree::PreOrder(void(*visit)(T item))
{
PreOrder(root,Visit);
}
template
inline void BinaryTree::PreOrder(BiTreeNode*& t, void(*visit)(T item))
{
if (t != NULL)
{
visit(t->data);
PreOrder(t->leftChild,visit);
PreOrder(t->rightChild,visit);
}
}
即DLR,也叫中根遍历、中序周游。可记作根左右。在二叉树中,中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。
template
inline void BinaryTree::InOrder(void(*visit)(T item))
{
InOrder(root,Visit);
}
template
inline void BinaryTree::InOrder(BiTreeNode*& t, void(*visit)(T item))
{
if (t != NULL)
{
InOrder(t->leftChild, visit);
visit(t->data);
InOrder(t->rightChild, visit);
}
}
即LRD,也叫后根遍历、后序变周游,可记作左右根。在二叉树中,首先遍历左子树,然后遍历右子树,最后访问根结点。
template
inline void BinaryTree::PostOrder(void(*visit)(T item))
{
PostOrder(root,Visit);
}
template
inline void BinaryTree::PostOrder(BiTreeNode*& t, void(*visit)(T item))
{
if (t != NULL)
{
PostOrder(t->leftChild, visit);
PostOrder(t->rightChild, visit);
visit(t->data);
}
}
template
inline void BinaryTree::DeleteSubTree(BiTreeNode*& t)
{
if (t == NULL)
return;
else
{
BiTreeNode* q=t->leftChild, *p;
while (q != NULL)
{
p = q->rightChild;
DeleteSubTree(q);
q = p;
}
delete t;
t = NULL;
}
}
在此实现中,对于二叉树结点的插入基本与二叉搜索树相同。当根结点为空时,新插入的结点作为根结点。当新插入的结点值小于根结点值时,插入到左子树;当新插入的结点值大于根结点值时,插入到右子树。
template
inline void BinaryTree::InsertChild(const T& value)
{
Insert(value, root);
}
template
inline void BinaryTree::Insert(const T& value, BiTreeNode*& t)
{
if (t == NULL)
t = new BiTreeNode(value);
else if (value < t->data)
{
Insert(value, t->leftChild);
}
else if (value > t->data)
{
Insert(value, t->rightChild);
}
else
return;
}
int main()
{
BinaryTreeBiTree;
BiTree.InsertChild(15);
BiTree.InsertChild(5);
BiTree.InsertChild(6);
BiTree.InsertChild(8);
BiTree.InsertChild(20);
BiTree.InsertChild(22);
BiTree.InsertChild(16);
BiTree.InsertChild(18);
cout << "前序:" << endl;
BiTree.PreOrder(Visit);
cout << endl << "中序:" << endl;
BiTree.InOrder(Visit);
cout << endl << "后序:" << endl;
BiTree.PostOrder(Visit);
cout << endl;
BiTree.clear();
cout << "前序:" << endl;
BiTree.PreOrder(Visit);
system("pause");
return EXIT_SUCCESS;
}
执行结果:
[外链图片转存失败(img-ojmDeH2F-1565276184605)(执行结果.PNG)]
二叉树的实现源码