1.题目
BT模板类 维护
2.数据结构与算法
BinNode:父节点、左孩子、右孩子、数据域、高度
BinTree:根节点指针、规模
3.源代码
#include "stdafx.h"
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
#define BinNodePosi(T) BinNode<T>*
#define stature(p) ((p)? (p)->height : -1)
#define HasLChild(x) ((x).lChild)
#define HasRChild(x) ((x).rChild)
//BinNode
template<typename T> struct BinNode{
//成员
BinNodePosi(T) parent, lChild, rChild; //父亲、孩子
T data; //数据域
int height; //高度
//构造函数
BinNode(T e, BinNodePosi(T) p = NULL, BinNodePosi(T) lc = NULL, BinNodePosi(T) rc = NULL, int h = 0)
:data(e), parent(p), lChild(lc), rChild(rc), height(h){}
//操作接口
int size(); //包含自身子树规模
BinNodePosi(T) insertAsLC(T const &); //作为当前节点的左孩子插入
BinNodePosi(T) insertAsRC(T const &); //作为当前节点的右孩子插入
template<typename T, typename VST> static void visitAlongLeftBranch(stack<BinNodePosi(T)> &, BinNodePosi(T), VST &);
template<typename T, typename VST> static void goAlongLeftBranch(stack<BinNodePosi(T)> &, BinNodePosi(T), VST &);
template<typename T> static void gotoHLVF(stack<BinNodePosi(T)> &);
template<typename VST> void travlevel(VST &); //层次遍历
template<typename VST> void travPre(VST &); //先序遍历
template<typename VST> void travIn(VST &); //中序遍历
template<typename VST> void travPost(VST &); //后序遍历
//先序遍历各版本
template<typename T, typename VST> void travPre_R(BinNodePosi(T), VST &);
template<typename T, typename VST> void travPre_I1(BinNodePosi(T), VST &);
template<typename T, typename VST> void travPre_I2(BinNodePosi(T), VST &);
//中序遍历各版本
template<typename T, typename VST> void travIn_R(BinNodePosi(T), VST &);
template<typename T, typename VST> void travIn_I(BinNodePosi(T), VST &);
//后序遍历个版本
template<typename T, typename VST> void travPost_R(BinNodePosi(T), VST &);
template<typename T, typename VST> void travPost_I(BinNodePosi(T), VST &);
};
//操作接口
template<typename T> int BinNode<T>::size(){
int s = 1; //计入自身
if(lChild) s += lChild.size(); //递归计入左孩子的规模
if(rChild) s += rChild.size(); //递归计入右孩子的规模
return s;
} //o(n)
template<typename T> BinNodePosi(T) BinNode<T>::insertAsLC(T const &e){
return lChild = new BinNode<T>(e, this);
} //o(1)
template<typename T> BinNodePosi(T) BinNode<T>::insertAsRC(T const &e){
return rChild = new BinNode<T>(e, this);
}//o(1)
template<typename T1> template<typename T, typename VST> static void BinNode<T1>::visitAlongLeftBranch(stack<BinNodePosi(T)> &s, BinNodePosi(T) x, VST &visit){
while(x){
visit(x);
if(HasRChild(x)) s.push(x->rChild);
x = x->lChild;
}
}
template<typename T1> template<typename T, typename VST> static void BinNode<T1>::goAlongLeftBranch(stack<BinNodePosi(T)> &s, BinNodePosi(T) x, VST &visit){
while(x){
s.push(x);
if(HasLChild(x)) x = x->lChild;
}
}
template<typename T1> template<typename T> static void BinNode<T1>::gotoHLVF(stack<BinNodePosi(T)> &s){
while(BinNodePosi(T) x = s.top()){
if(HasLChild(*x)){
if(HasRChild(*x)) s.push(x->rChild);
s.push(x->lChild);
}else{
s.push(x->rChild);
}
}
s.pop();
}
//先序遍历
template<typename T> template<typename VST> void BinNode<T>::travPre(VST & visit){
switch(rand()%3){
case 1: travPre_R(this, visit);break;
case 2: travPre_I1(this, visit);break;
default: travPre_I2(this, visit);break;
}
}
//先序遍历各版本
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travPre_R(BinNodePosi(T) x, VST &visit){
if(!x) return;
visit(x->data);
travPre_R(x->lChild, visit);
travPre_R(x->rChild, visit);
}
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travPre_I1(BinNodePosi(T) x, VST &visit){
stack<BinNodePosi(T)> s; //辅助栈
if(x) s.push(x); //根节点入栈
while(!s.empty()){
x = s.top();s.pop();visit(x);
if(HasLChild(*x)) s.push(x->rChild); //右孩子先入栈
if(HasRChild(*x)) s.push(x->lChild); //左孩子后入栈
}
}
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travPre_I2(BinNodePosi(T) x, VST &visit){
if(!x) return;
stack<BinNodePosi(T)> s;
while(true){
visitAlongLeftBranch(s, x, visit);
if(s.empty()) break;
x = s.top(); s.pop();
}
}
//中序遍历
template<typename T> template<typename VST> void BinNode<T>::travIn(VST &visit){
switch(rand()%2){
case 1: travIn_R(this, visit);break;
default: travIn_I(this, visit);break;
}
}
//中序遍历各版本
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travIn_R(BinNodePosi(T) x, VST &visit){
if(!x) return;
travIn_R(x->lChild, visit);
visit(x->data);
travIn_R(x->rChild, visit);
}
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travIn_I(BinNodePosi(T) x, VST &visit){
stack<BinNodePosi(T)> s;
while(true){
goAlongLeftBranch(x);
if(s.empty()) break;
x = s.top(); s.pop();
visit(x);
x = x->rChild;
}
}
//后序遍历
template<typename T> template<typename VST> void BinNode<T>::travPost(VST &visit){
switch(rand()%2){
case 1: travPost_R(this, visit);break;
default: travPost_I(this, visit);break;
}
}
//后序遍历各版本
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travPost_R(BinNodePosi(T) x, VST &visit){
if(!x) return;
travIn_R(x->lChild, visit);
travIn_R(x->rChild, visit);
visit(x->data);
}
template<typename T1> template<typename T, typename VST> void BinNode<T1>::travPost_I(BinNodePosi(T) x, VST &visit){
stack<BinNodePosi(T)> s;
if(x) s.push(x);
while(!s.empty()){
if(s.top() != x->parent)
goAlongLeftBranch(s);
x = s.top(); s.pop();
visit(x);
}
}
//层次遍历
template<typename T> template<typename VST> void BinNode<T>::travlevel(VST &visit){
queue<BinNodePosi(T)> q;
q.push(this);
BinNodePosi(T) x;
while(!q.empty()){
x = q.front(); q.pop();visit(x->data);
if(HasLChild(*x)) q.push(x->lChild);
if(HasRChild(*x)) q.push(x->rChild);
}
}
/********华丽的分割线************************************************************************************************/
//BinTree模板类
template<typename T> class BinTree{
protected:
int _size; //规模
BinNodePosi(T) _root;
virtual int updateHeight(BinNodePosi(T) x); //更新节点x的高度
void updateHeightAbove(BinNodePosi(T) x); //更新节点x及其祖先的高度
public:
int size() const{ return _size;}
bool empty() const{ return !_root;}
BinNodePosi(T) root() const{return _root;}
BinNodePosi(T) insertAsLC(BinNodePosi(T) x, T const &);
BinNodePosi(T) insertAsRC(BinNodePosi(T) x, T const &);
template<typename VST> void travLevel(VST &visit){
if(_root) _root->travlevel(visit);
}
template<typename VST> void travPre(VST &visit){
if(_root) _root->travPre(visit);
}
template<typename VST> void travIn(VST &visit){
if(_root) _root->travIn(visit);
}
template<typename VST> void travPost(VST &visit){
if(_root) _root->travPost(visit);
}
};
//操作接口
template<typename T> int BinTree<T>::updateHeight(BinNodePosi(T) x){
return x->height = 1 + max(stature(x->lChild), stature(x->rChild));
}
template<typename T> void BinTree<T>::updateHeightAbove(BinNodePosi(T) x){
while(x){
updateHeight(x);
x = x->parent;
}
}
template<typename T> BinNodePosi(T) BinTree<T>::insertAsLC(BinNodePosi(T) x, T const &e){
_size++; x->insertAsLC(e);
updateHeightAbove(x);
return x->lChild;
}
template<typename T> BinNodePosi(T) BinTree<T>::insertAsRC(BinNodePosi(T) x, T const &e){
_size++; x->insertAsRC(e);
updateHeightAbove(x);
return x->rChild;
}
4.时间复杂度
5.结论
树:最小连通图、最大无环图
根据长子、兄弟表示法,外加有根、有序的条件,所有树都可以转化为二叉树。
所以只需研究二叉树BT。
如有错误,请您批评指正。
参考书籍:清华大学《数据结构(C++语言版)》(第三版) 邓俊辉