其他分享
首页 > 其他分享> > 8.1 伸展树

8.1 伸展树

作者:互联网

一、伸展树

template<typename T>
class Splay:public BST<T>{//由BST派生
	protected:BinNodePosi(T) splay(BinNodePosi(T) v);//将v伸展至根
	public://伸展树的查找也会引起整树的结构调整,故search()也需要重写
		BinNodePosi(T) & search(const T & e);//查找(重写)
		BinNodePosi(T) insert(const T & e);//插入(重写)
		bool remove(const T& e);//删除(重写)
}; 
template <typename T> BinNodePosi(T) v){
	if(!v) return NULL; BinNodePosi(T) p; BinNodePosi(T) g;//父亲、祖父
	while((p = v->parent) && (g = p->parent)){//自下而上,反复双层伸展
		BinNodePosi(T) gg = g->parent;//每轮之后,v都将以原曾祖父为父
		if(IsLChild(*v))
			if(LsLChild(*p)){/*zig - zig*/}else{/* zig - zag*/}
		else if(IsRChild(*p)){/*zag - zag*/}else{/*zag - zig*/}
		//每经过一次双层伸展,我们都需要将局部这棵新的子树接入到原树中对应 的位置,并更新相应节点的高度信息
		if(!gg) v->parent = NULL;//若无曾祖父gg,则v现即为树根;否则,gg此后应为以v为左或右孩子
		else(g == gg->lc)?attachAsLChild(gg, v):attachAsRChild(gg, v);
		updateHeight(g); updateHeight(p); updateHeight(v);
	}//双层伸展结束时,必有g == NULL,但p可能非空
	if(p = v->parent){/*若p为根,只需在额外单旋(至多一次)*/}
	v->parent = NULL; return v;//伸展完成,v抵达树根
}

在这里插入图片描述

//使用直接拼接的方式实现左旋或右旋
if(IsLChild(*v))
	if(IsLChild(*p)){
		attachAsLChild(g, p->rc);//p的右孩子当作g的左孩子
		attachAsLChild(p, v->rc);
		attachAsRChild(p, g);
		attachAsRChild(v, p);
	}else{/*zig - zag*/}
else
	if(IsRChild(*p)){/*zag - zag*/}
	else{/*zag - zag*/}
template <typename T> BinNodePosi(T) & Splay<T>::search(const T& e){
	//调用标准BST的内部接口定位目标节点
	BinNodePosi(T) p = searchIn(_root, e, _hot = NULL);
	//无论成功与否,最后被访问的节点都将伸展至根
	_root = splay(p ? p : _hot);
	//总是返回根节点
	return _root;
}

标签:8.1,parent,BinNodePosi,zag,zig,节点,伸展
来源: https://blog.csdn.net/weixin_45781228/article/details/119087549