- 说明
- 基于链表实现的子结点表示法
- 参考资料
一、说明:
1、关于二叉链表,(百度百科上的自相矛盾了,引用日期:2018-11-8),也没找着一个确切的说法,有说两个指针一个指向左孩子一个右孩子的,也有说是两个指针一个指向左孩子一个指向兄弟的。在本文中指的是前者(一个指向左孩子,一个指向右孩子);
2、部分说明参考上一篇https://blog.csdn.net/qq_40889820/article/details/83795341;
3、以下代码仅供参考。
二、基于链表实现的子结点表示法
1、BinNode.h
#include<iostream>
using namespace std;
#ifndef _BinNode
#define _BinNode
namespace wangzhe
{
template<typename E>
class BinNode
{
private:
E it;
BinNode* lc;
BinNode* rc;
public:
BinNode()
{
lc=rc=NULL;
}
BinNode(E e,BinNode* l,BinNode* r)
{
it=e;lc=l;rc=r;
}
E& element()
{
return it;
}
void setElement(const E& e)
{
it=e;
}
BinNode* left() const
{
return lc;
}
void setLeft(BinNode* b)
{
lc=b;
}
BinNode* right() const
{
return rc;
}
void setRight(BinNode* b)
{
rc=b;
}
bool isLeaf()
{
return (lc==NULL)&&(rc==NULL);
}
};
}
#endif
2、BinTree.h
#include<iostream>
using namespace std;
#include"BinNode.h"
#ifndef _BinTree
#define _BinTree
namespace wangzhe
{
template<typename E>
class BinTree
{
private:
BinNode<E>* root;//根结点
public:
BinTree();//构造函数
~BinTree();//析构函数
BinNode<E>* createBinTree();//前序遍历输入一棵二叉树
void clear(BinNode<E>* r);//销毁一颗二叉树
BinNode<E>* Root();//返回根节点
void setRoot(BinNode<E>* r);//设置根节点
bool isEmpty(BinNode<E>* r);//判断二叉树是否为空
void preorder(BinNode<E>* r);//前序遍历
void inorder(BinNode<E>* r);//中序遍历
void postorder(BinNode<E>* r);//后序遍历
void levelorder(BinNode<E>* r);//层次遍历
int BinTreeDepth(BinNode<E>* r);//二叉树深度
int count(BinNode<E>* r);//二叉树结点数
};
}
#endif
3、BinTree.cpp
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#include"BinTree.h"
namespace wangzhe
{
template<typename E>
BinTree<E>::BinTree()
{
root=NULL;
}
template<typename E>
BinTree<E>::~BinTree()
{
clear(root);
}
template<typename E>
BinNode<E>* BinTree<E>::createBinTree()
{
E ele;
cin>>ele;
BinNode<E>* rt;
if(ele=='#') rt=NULL;
else
{
rt=new BinNode<E>;
rt->setElement(ele);
rt->setLeft(createBinTree());
rt->setRight(createBinTree());
}
return rt;//返回根结点
}
template<typename E>
void BinTree<E>::clear(BinNode<E>* r)
{
if(r==NULL) return;//空树,直接返回
//只有一个结点
if(r->left()==NULL&&r->right()==NULL)
{
delete r;
r=NULL;
return;
}
//大于一个结点,递归销毁左子树与右子树
clear(r->left());
clear(r->right());
delete r;
r=NULL;
}
template<typename E>
BinNode<E>* BinTree<E>::Root()
{
return root;
}
template<typename E>
void BinTree<E>::setRoot(BinNode<E>* r)
{
root=r;
}
template<typename E>
bool BinTree<E>::isEmpty(BinNode<E>* r)
{
return root==NULL;
}
template<typename E>
void BinTree<E>::preorder(BinNode<E>* r)
{
if(r==NULL) return;
cout<<r->element() <<' ';
preorder(r->left());
preorder(r->right());
}
template<typename E>
void BinTree<E>::inorder(BinNode<E>* r)
{
if(r==NULL) return;
inorder(r->left());
cout<<r->element()<<' ';
inorder(r->right());
}
template<typename E>
void BinTree<E>::postorder(BinNode<E>* r)
{
if(r==NULL) return;
postorder(r->left());
postorder(r->right());
cout<<r->element()<<' ';
}
template<typename E>
void BinTree<E>::levelorder(BinNode<E>* r)
{
queue<BinNode<E>*> q;
if(r) q.push(r);
BinNode<E>* temp;
while(!q.empty())
{
temp=q.front();
q.pop();
cout<<temp->element()<<' ';
if(temp->left()) q.push(temp->left());
if(temp->right()) q.push(temp->right());
}
}
template<typename E>
int BinTree<E>::BinTreeDepth(BinNode<E>* r)
{
if(r==NULL) return 0;
else return max(BinTreeDepth(r->left()),BinTreeDepth(r->right()))+1;
}
template<typename E>
int BinTree<E>::count(BinNode<E>* r)
{
if(r==NULL) return 0;
else return 1+count(r->right())+count(r->left());
}
}
4、main.cpp
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#include"BinTree.h"
#include"BinTree.cpp"
using namespace wangzhe;//ABD##E##CG##H##
int main(int argc, char** argv)
{
for(int i=1;i<=50;i++) cout<<'*';
cout<<"\n实验三:二叉树的物理实现(二叉链表实现)\n";
for(int i=1;i<=50;i++) cout<<'*';
cout<<endl;
BinTree<char> tree;
BinNode<char>* rt;
cout<<"请以前序遍历的顺序输入一棵树(结点元素类型为字符型),空节点以#代替。"<<endl;
cout<<"例如:AB#D##CE##F##"<<endl;
rt=tree.createBinTree() ;
tree.setRoot(rt);
cout<<"这棵树是否是空树?\n";
if(tree.isEmpty(rt)) cout<<"是,结束操作\n";
else
{
cout<<"不是,继续以下操作\n";
cout<<"这棵二叉树前序遍历的结果为:\n" ;
tree.preorder(rt); cout<<endl;
cout<<"这棵二叉树中序遍历的结果为:\n" ;
tree.inorder(rt);cout<<endl;
cout<<"这棵二叉树后序遍历的结果为:\n" ;
tree.postorder(rt);cout<<endl;
cout<<"这棵二叉树层次遍历的结果为:\n" ;
tree.levelorder(rt);cout<<endl;
cout<<"这棵二叉树的高度是:\n" ;
cout<<tree.BinTreeDepth(rt)<<endl;
cout<<"这棵二叉树的结点个数是:\n" ;
cout<<tree.count(rt)<<endl;
}
return 0;
}
5、运行结果
三、参考资料
1、gogogo_sky_求二叉树的高度/销毁一颗二叉树【递归思想】
2、Clifford A.Shaffer.数据结构与算法分析【M】.北京:电子工业出版社,2013:99-102.