注意:
1.成员函数指针的声明/定义及使用(typedef void(BinaryTree::*VISIT)(treenode *node);)
2. destroy时不能进行前序/中序遍历,最好使用非递归的层次遍历进行删除
3.在类外部不能使用含有模板的typedef,但是在类内部可以(为什么?未知!)
4.实现参考的是《C++数据结构与算法分析》第八章,但有所修改(size实现源代码使用的是static int作为计数器)
5.注意层次遍历的实现——借助于queue
#pragma once
#include <queue>
#include <iostream>
using namespace std;
//• 确定其高度。
//• 确定其元素数目。
//• 复制。
//• 在屏幕或纸上显示二叉树。
//• 确定两棵二叉树是否一样。
//• 删除整棵树。
//• 若为数学表达式树,计算该数学表达式。
//• 若为数学表达式树,给出对应的带括号的表达式。
//
//有四种遍历二叉树的方法:
//• 前序遍历。
//• 中序遍历。
//• 后序遍历。
//• 逐层遍历
template<typename T>
class treenode
{
public:
treenode():m_pleftnode(nullptr),m_prightnode(nullptr){}
treenode(const T &t) :m_data(t), m_pleftnode(nullptr), m_prightnode(nullptr) {}
treenode(const T &t, treenode<T> * leftnode, treenode<T> * righttree):m_data(t),m_pleftnode(leftnode),m_prightnode(righttree){}
treenode(const treenode<T> &t):m_data(t.m_data), m_pleftnode(t.m_pleftnode), m_prightnode(t.m_prightnode) {}
T m_data;
treenode<T> *m_pleftnode;
treenode<T> *m_prightnode;
};
//template<typename T>
//struct visitex
//{
// typedef void(*visit)(treenode<T> *node);
//};
//template<typename T>
//using VISIT = visitex<T>::visit;
//定义一个辅助class
//template<class T>
//struct bar {
// typedef void(*pfun)(T t);
//};
//然后用的时候
//bar<int>::pfun ptr;
template<typename T>
class BinaryTree
{
public:
//template<typename T>
typedef void(*visit)(treenode<T> *node);
typedef void(BinaryTree<T>::*VISIT)(treenode<T> *node);
BinaryTree() :m_proot(nullptr) {
m_increase = &BinaryTree<T>::increase; m_pOutPutNode = &BinaryTree<T>::OutPutNode;
}
BinaryTree(const treenode<T> & t)
{
m_proot = new treenode<T>(t);
m_increase = &BinaryTree<T>::increase;
m_pOutPutNode = &BinaryTree<T>::OutPutNode;
m_freeFunc = &BinaryTree<T>::free;
}
~BinaryTree()
{
destroy(m_proot);
}
void increase(treenode<T> *node)
{
m_count++;
}
void OutPutNode(treenode<T> *node)
{
cout << node->m_data << " ";
}
int size()
{
m_count = 0;
LevelOrder(m_increase);
return m_count;
}
int Height()
{
return Height(m_proot);
}
void destroy(treenode<T> *node)
{
LevelOrder(m_freeFunc,node);
node = nullptr;
}
void MakeTree(const T &t, BinaryTree<T> &lefttree, BinaryTree<T> &righttree)
{
destroy(m_proot);
m_proot = new treenode<T>(t,lefttree.m_proot,righttree.m_proot);
lefttree.m_proot = righttree.m_proot = nullptr;
}
bool BreakTree(T &t, BinaryTree<T> &lefttree, BinaryTree<T> &righttree)
{
if (isEmpty())
{
return false;
}
t = m_proot->m_data;
if (!lefttree.isEmpty())
{
destroy(lefttree.m_proot);
}
if (!righttree.isEmpty())
{
destroy(lefttree.m_proot);
}
lefttree.m_proot = m_proot->m_pleftnode;
righttree.m_proot = m_proot->m_prightnode;
delete m_proot;
m_proot = nullptr;
return true;
}
treenode<T> *getRoot()
{
return m_proot;
}
bool getRootData(T &x)
{
if (isEmpty())
{
return false;
}
x = m_proot->m_data;
return true;
}
bool isEmpty() { return (m_proot == nullptr); }
void PreOrder(VISIT v, treenode<T> *node)
{
if (node != nullptr)
{
(this->*v)(node);
PreOrder(v, node->m_pleftnode);
PreOrder(v, node->m_prightnode);
}
}
void InOrder(VISIT v, treenode<T> *node)
{
if (node != nullptr)
{
InOrder(v, node->m_pleftnode);
v(node);
InOrder(v, node->m_prightnode);
}
}
void PostOrder(VISIT v, treenode<T> *node)
{
if (node != nullptr)
{
PostOrder(v, node->m_pleftnode);
PostOrder(v, node->m_prightnode);
v(node);
}
}
void LevelOrder(VISIT v, treenode<T> * node = nullptr)
{
treenode<T> *tmp = m_proot;
if (node != nullptr)
{
tmp = node;
}
queue<treenode<T>*> que;
if (tmp != nullptr)
{
que.push(tmp);
while (!que.empty())
{
tmp = que.front();
que.pop();
if (tmp->m_pleftnode != nullptr)
{
que.push(tmp->m_pleftnode);
}
if (tmp->m_prightnode != nullptr)
{
que.push(tmp->m_prightnode);
}
(this->*v)(tmp);
}
}
}
VISIT m_pOutPutNode;
private:
int Height(treenode<T> * node)
{
if (nullptr == node)
{
return 0;
}
int hl = Height(node->m_pleftnode);
int hr = Height(node->m_prightnode);
if (hl > hr)
{
return ++hl;
}
return ++hr;
}
void free(treenode<T> * node)
{
delete node;
}
VISIT m_freeFunc;
treenode<T> *m_proot;
VISIT m_increase;
int m_count ;
};
#include "binarytree.h"
#include <iostream>
using namespace std;
int main()
{
BinaryTree<int> tree1;
BinaryTree<int> treeleft_level1_2(8);
treeleft_level1_2.MakeTree(2, BinaryTree<int>(4), BinaryTree<int>(5));
BinaryTree<int> treeright_level1_2;
treeright_level1_2.MakeTree(3, BinaryTree<int>(6), BinaryTree<int>());
tree1.MakeTree(1, treeleft_level1_2, treeright_level1_2);
tree1.PreOrder(tree1.m_pOutPutNode,tree1.getRoot());
cout << endl;
tree1.LevelOrder(tree1.m_pOutPutNode);
cout << endl;
cout << "count of tree1:" << tree1.size() << endl;
cout << "Height of tree1:" << tree1.Height() << endl;
return 0;
}