温存温存9.1

描述
创建二叉树类。二叉树的存储结构使用链表。提供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。

格式
输入格式
第一行为一个数字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;
int counts[999999];//计算树的节点的数组 
int deep[999999];//计算树的高度的数组 
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;//根节点指针
		int treeSize;//元素个数
	public:
		BinaryTree():root(NULL),treeSize(0){
    
    }//构造 
		~BinaryTree(){
    
    erase(root);}//析构 
		bool empty()const {
    
    return treeSize==0;}
		int size()const{
    
    return treeSize;} 
		binaryTreeNode<T>** rootElement(){
    
    return &root;}//返回根节点 
		void preOrder(binaryTreeNode<T>*);
		void inOrder(binaryTreeNode<T>*);
		void postOrder(binaryTreeNode<T>*);
		void levelOrder();
		void erase(binaryTreeNode<T>*&proot);
		int height(binaryTreeNode<T>*t);//高度 
		int treeCount(binaryTreeNode<T>*t);//节点树 
		void makeTree(T* element,int n);
		void visit(binaryTreeNode<T>*t);
};
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>::preOrder(binaryTreeNode<T>*t){
    
    //前序遍历 
	if(t!=NULL){
    
    //根左右 
	    //t->element代表第几个节点,与值一样 
		counts[(t->element)-1]=treeCount(t);//counts数组表示以第几个节点为跟的节点个数 
		deep[(t->element)-1]=height(t);//deep表示以第几个节点为跟的节点高度 
		//visit(t);
		preOrder(t->leftChild);
		preOrder(t->rightChild);
	}
}
template<class T>
void BinaryTree<T>::inOrder(binaryTreeNode<T>*t){
    
    //中序遍历 
	if(t!=NULL){
    
    
		inOrder(t->leftChild);
		visit(t);//访问根节点 
		inOrder(t->rightChild);
	}
}
template<class T>
void BinaryTree<T>::postOrder(binaryTreeNode<T>*t){
    
    //后序遍历
	if(t!=NULL){
    
    
		postOrder(t->leftChild);
		postOrder(t->rightChild);
		visit(t);
	} 
} 
template<class T>
void BinaryTree<T>::levelOrder(){
    
    //层次遍历
	binaryTreeNode <T>* q[treeSize];//数组型指针 
    q[0]=root;//指针指向头节点 
    cout<<q[0]->element<<" ";
    for(int i=1;i<treeSize;i++){
    
    
   		int index=0;//重置 
   		while(q[index]==NULL||q[index]->leaves==1){
    
    //当q【leave】被值1时,该节点完成任务,就代表需要++来转下一个值了
   			index++;
		}
   		if(i%2!=0){
    
    
   			q[i]=q[index]->leftChild;
   			if(q[i]!=NULL)
   				cout<<q[i]->element<<" ";
   		}else{
    
    //转到右节点就得转下一个节点了,所以leave值1 
   			q[i]=q[index]->rightChild;
   			q[index]->leaves=1;
   			if(q[i]!=NULL)
   				cout<<q[i]->element<<" ";
		}
   }
}
template <class T>
int BinaryTree<T>::height(binaryTreeNode<T> *t){
    
    //递归求树的高度 
//hl,hr每次循环都更新 
   if (t == NULL)
      return 0;                    // 空
   int hl = height(t->leftChild);  // 左边高度 
   int hr = height(t->rightChild); // 右边高度 
   if (hl > hr)
      return ++hl;
   else
      return ++hr;
}
template<class T>
int BinaryTree<T>::treeCount(binaryTreeNode<T>*t){
    
    //递归求出树的节点的数目 
//深入到叶节点一个一个累加上来 
	int n=0;
	if(t!=NULL){
    
    
		n=treeCount(t->leftChild)+treeCount(t->rightChild)+1;
	}
	return n;
}
template<class T>
void BinaryTree<T>::makeTree(T*elem,int n){
    
    
    binaryTreeNode <T>* *(array[n/2])={
    
    };//binaryTreeNode类型的指针,且是一个数组型指针,既每个数都是一个指针 
    array[0]=&root;//起点 
    //array[0]是root的地址,既指向root 
    root=new binaryTreeNode<T>;
	root->element=elem[0];
	root->leftChild=NULL;
	root->rightChild=NULL;
	root->leaves=0;
	for(int i=1;i<n;i++){
    
    
		int index=(i-1)/2;//保证左右孩子在同一层 
		binaryTreeNode<T>* p=new binaryTreeNode<T>;
		if(elem[i]!=-1){
    
    
			p->element=elem[i];
			p->leftChild=NULL;
			p->rightChild=NULL;
			p->leaves=0;
		}else
			p=NULL;
		if(i%2!=0){
    
    
			(*array[index])->leftChild=p;//代表当前节点的左孩子 
			//(*array[0])代表就是root本身 
			if(p!=NULL)
				//寻找下一个节点,eg:a[0]-->a[1]-->a[2] 
				array[(p->element)-1]=&((*array[index])->leftChild);//array[(p->element)-1]再指向 (*array[index])->leftChild
				                                        //因此当出现与 array[(p->element)-1]相同的array[index]便实现树的生长 
		}else{
    
    
			(*array[index])->rightChild=p;//当前节点的有孩子 
			if(p!=NULL)
				array[(p->element)-1]=&((*array[index])->rightChild);
		}	
    }
    treeSize=n;
}
int main(){
    
    
	BinaryTree<int> tree;
    int n;cin>>n;
	int *num=new int[2*n+1];
	num[0]=1;
	for(int i=1;i<=(2*n);i++){
    
    //输入节点值,注意要符合节点的序号 
		cin>>num[i];
	}
	tree.makeTree(num,2*n+1);
	tree.levelOrder();
	cout<<endl;
	binaryTreeNode<int>* node=*tree.rootElement();
	tree.preOrder(node);//为count和deep赋值 
	for(int i=0;i<n;i++)
		cout<<counts[i]<<" ";
	cout<<endl;
	for(int i=0;i<n;i++)
		cout<<deep[i]<<" ";	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_51406030/article/details/121344511
9.1