描述
创建二叉树类。二叉树的存储结构使用链表。提供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。
格式
输入格式
第一行为一个数字n (10<=n<=100000),表示有这棵树有n个节点,编号为1~n。
之后n行每行两个数字,第 i 行的两个数字a、b表示编号为 i 的节点的左孩子节点为 a,右孩子节点为 b,-1表示该位置没有节点。
保证数据有效,根节点为1。
输出格式
第一行,n个数字,表示该树的层次遍历。
第二行,n个数字,第i个数字表示以 i 节点为根的子树的节点数目。
第三行,n个数字,第i个数字表示以 i 节点为根的子树的高度。
#include<iostream>
using namespace std;
template<class T>
struct binaryTreeNode{
T element;
int leaves;
binaryTreeNode<T> *leftChild,*rightChild;
binaryTreeNode():leftChild(NULL),rightChild(NULL){
}
binaryTreeNode(const T&theElement):element(theElement){
leftChild=rightChild=NULL;
}
binaryTreeNode(const T&theElement,binaryTreeNode* theLeftChild,binaryTreeNode* theRightChild){
element=theElement;
leftChild=theLeftChild;
rightChild=theRightChild;
}
};
template<class T>
class BinaryTree{
private:
binaryTreeNode<T> *root;
public:
BinaryTree(){
root=NULL;}
~BinaryTree(){
erase(root);}
void visit(binaryTreeNode<T>*t);
void erase(binaryTreeNode<T>*&proot);
void postOrder(binaryTreeNode<T>*t);
binaryTreeNode<T>*makeTree(T* preOrder,T* inOrder,int P0,int Pn,int I0,int In);
};
template<class T>
void BinaryTree<T>::visit(binaryTreeNode<T>*t){
cout<<t->element<<" ";
}
template<class T>
void BinaryTree<T>::erase(binaryTreeNode<T>*&proot){
if(proot!=NULL){
erase(proot->leftChild);
erase(proot->rightChild);
delete proot;
proot=NULL;
}
}
template<class T>
void BinaryTree<T>::postOrder(binaryTreeNode<T>*t){
if(t!=NULL){
postOrder(t->leftChild);
postOrder(t->rightChild);
visit(t);
}
}
template<class T>
binaryTreeNode<T>* BinaryTree<T>::makeTree(T*preOrder,T*inOrder,int P0,int Pn,int I0,int In){
//递归重组树
int i;
binaryTreeNode<T> *num=new binaryTreeNode<T>;
num->element=preOrder[P0];
num->leftChild=NULL;
num->rightChild=NULL;
if(P0==Pn&&I0==In)
return num;
for(i=I0;i<=In;i++)
if(preOrder[P0]==inOrder[i])//找出根所在的位置i
break;
int leftLength=i-I0;//左孩子数量 //因为根据中序遍历的特性,在根左边都是左孩子,右边都是右孩子
int rightLength=In-i;//右孩子数量
if(leftLength>0)
//拿出左支树
num->leftChild=makeTree(preOrder,inOrder,P0+1,P0+leftLength,I0,i-1);//P0+1到P0+leftLength代表拿掉第一个根,之后剩下的所有左孩子
//i是根,所以i-1为左孩子的全部
if(rightLength>0)
//同理拿出右支树
num->rightChild=makeTree(preOrder,inOrder,P0+leftLength+1,Pn,i+1,In);//P0+leftLength+1,拿出所有右孩子//i的右边都是右孩子
root=num;
return num;
}
int main()
{
BinaryTree<int> tree;
int *preOrder,*inOrder,n;
cin>>n;
preOrder=new int[n];
inOrder=new int[n];
for(int i=0;i<n;i++)
cin>>preOrder[i];
for(int j=0;j<n;j++)
cin>>inOrder[j];
binaryTreeNode<int> *p=tree.makeTree(preOrder,inOrder,0,n-1,0,n-1);
tree.postOrder(p);
return 0;
}