数据结构(邓俊辉):二叉树(2.实现)

本文介绍了二叉树节点的模板类定义,包括数据、父节点、子节点和高度等成员,以及构造函数和各种操作接口。详细阐述了二叉树的先序、中序和后序递归遍历以及迭代遍历的方法。同时,文章表达了作者在学习过程中不断发现规律和优化代码的重要性,并表示会继续深入学习和实践。
摘要由CSDN通过智能技术生成

基本组成单位:二叉树节点,边对应于节点间的相互引用。
二叉树节点的模板类:

template <typename T>
struct BinNode {
	//成员
	T data;
	BinNodePosi(T) parent; BinNodePosi(T) lc; BinNodePosi(T) rc;
	int height;
	
	//构造函数
	BinNode() : parent(NULL), lc(NULL), rc(NULL), height(0){}
	BinNode(T e, BinNodePosi(T) p = NULL, BinNodePosi(T) lc = NULL, BinNodePosi(T) rc = NULL, int h = 0):
		data(e), parent(p), lc(lc), rc(rc), hright(h) {}
		
	//操作接口
	int size();//当前节点后代总数
	BinNodePosi(T) insertAsLc (T const&); //作为左子树插入
	BinNodePosi(T) insertAsRc (T const&); //作为右子树插入
	BinNodePosi(T) succ; // 当前节点的直接后继
	template<typename VST> void travLevel(VST&); //层次遍历
	template<typename VST> void travPre(VST&);   //先序遍历
	template<typename VST> void travIn(VST&);    //中序遍历
	template<typename VST> void travPOost(VST&); //后序遍历
	
	//比较器、判等器
	bool operator < (BinNode const& bn){
		return data < bn.data;
	}
	bool operator == (BinNode const& bn){
		return data == bn.data;
	}
};

template <typename T>
BinNodePosi(T) BinNode<T> :: insertAsLc (T const& e){
	return lc = new BinNode(e, this);
}

template <typename T>
BinNodePosi(T) BinNode<T> :: insertAsRc (T const& e){
	return rc = new BinNode(e, this);
}

二叉树的遍历:
(一)递归式遍历
1)先序遍历:先访问根节点,在访问左子树,再访问右子树。

template <typename T, typename VST>
void travPre_R (BinNodePosi(T) x, VST& visit){
	if(!x) return ;
	visit(x->data);
	travPre_R(x->lc, visit);
	travPre_R(x->rc, visit);
}

2)中序遍历:左——>根——>右

template <typename T, typename VST>
void travIn_R (BinNodePosi(T) x, VST& visit){
	if(!x) return ;
	travIn_R(x->lc, visit);
	visit(x->data);
	travIn_R(x->rc, visit);
}

3)后序遍历:左——>右——>根

template <typename T, typename VST>
void travPost_R (BinNodePosi(T) x, VST& visit){
	if(!x) return ;
	travPost_R(x->lc, visit);
	travPost_R(x->rc, visit);
	visit(x->data);
}

(二)迭代式遍历
1)先序遍历:
迭代版本1:

template <typename T, typename VST>
void travPre_I1(BinNodePosi(T) x, VST& visit){
	Stack <BinNodePosi(T)> S;
	if(x) S.push(x);
	while(!S.empty()){
		x = S.pop(); visit(x->data);
		id(HasRChild(*x)) S.push(x->rChild);
		id(HasLChild(*x)) S.push(x->lChild);
	}
}

迭代版本2:

template <typename T, typename VST>
static void visitAlongLeftBranch(BinNodePosi(T) x, VSY& visit, Stack <BinNodePosi(T) &S0){
	while (x){
		visit(x->data);
		S.push(x->rChild);
		x = x->lChild;
	}
}
template <typename T, typename VST>
void travPre_I2 (BinNodePosi(T) x, VST& visit){
	Stack <BinNodePosi(T)> S;
	while (true){
		visitAlongLeftBranch(x, visit, S);
		if (S.empty()) break;
		x = S.pop();
	}
}

2)中序遍历

template <typename T>
static void goAlongLeftBranch(BinNodePosi(T) x, Stack<BinNodePosi(T)>& S){
	while (x){
		S.push(x); 
		x = x->lc;
	}
}
template <typename T, typename VST>
void travIn_I1 (BinNodePosi(T) x, VST& visit){
	Stack <BinNodePosi(T)> S;
	while (true){
		goAlongLeftBranch(x, S);
		if (S.empty()) break;
		x = S.pop(); visit(x->data);
		x = x->rc;
	}
}
//与先序遍历类似,只不过是从底向上访问。将入栈的每个左子树的节点视为根节点并访问,再转向右子树

PS.邓老师的数据结构难度还是有的,尤其是基础的语言不太熟悉的情况下,其实这本书学到这里,感觉更重要的是,不断地发现问题的规律并进行优化改进。我打算继续看完视频,写完这本书上的代码,最后估计还是会回来看很多遍的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值