二叉树BT 模板类实现

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++语言版)》(第三版) 邓俊辉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值