C++ 数据结构学习 ---- 红黑树

学习c++数据结构---红黑树
摘要由CSDN通过智能技术生成

目录

1. 头文件

1.1 红黑树头文件

2. 相关函数

2.1 插入函数

2.2 删除函数

2.3 更新高度

2.4 双黑调整

2.5 双红调整

3.完整代码

4.运行结果及截图

5. 逐步验证 


1. 头文件

1.1 红黑树头文件

注:需先引入C++ 数据结构学习 ---- 二叉搜索树_孤城寻欢的博客-CSDN博客的文件

#include "BST.h"


//外部节点也视作黑节点
#define IsBlack(p) ( ! (p) || ( RB_BLACK == (p)->color ) ) 
//非黑即红
#define IsRed(p) ( ! IsBlack(p) ) 
/*RedBlack高度更新条件*/
#define BlackHeightUpdated(x) (  \
   ( stature( (x).lc ) == stature( (x).rc ) ) && \
   ( (x).height == ( IsRed(& x) ? stature( (x).lc ) : stature( (x).lc ) + 1 ) ) )
/*来自父亲的引用*/
#define FromParentTo( x ) \
( IsRoot(x) ? BST<T>::_root : ( IsLChild(x) ? (x).parent->lc : (x).parent->rc ) )

template <typename T> class RedBlack : public BST<T> { //RedBlack树模板类
protected:
	void solveDoubleRed(BinNodePosi(T) x); //双红修正
	void solveDoubleBlack(BinNodePosi(T) x); //双黑修正
	int updateHeight(BinNodePosi(T) x); //更新节点x的高度(重写)
public:
	BinNodePosi(T) insert(const T& e); //插入(重写)
	bool remove(const T& e); //删除(重写)
 // BST::search()等其余接口可直接沿用
};

2. 相关函数

2.1 插入函数

//将e插入红黑树
template <typename T> BinNodePosi(T) RedBlack<T>::insert(const T& e) {
    if (!BST<T>::_root ){
        BinNodePosi(T) xOld=BST<T>::search(e); if (xOld) return xOld;
         BST<T>::_root = new BinNode<T>(e, BST<T>::_hot, NULL, NULL, 1); BST<T>::_size++;//根节点黑色
         return xOld;
    }
    if ( BST<T>::_size < 3) {
        BinNodePosi(T) xOld= BST<T>::search(e); if (xOld) return xOld;
        if( BST<T>::_size<2 )
         this->_root->lc = new BinNode<T>(e, BST<T>::_hot, NULL, NULL, 0);//第二层红色
        else  
          this->_root->rc = new BinNode<T>(e, BST<T>::_hot, NULL, NULL, 0); //第二层红色
        BST<T>::_size++;
        return  xOld;
    }
	BinNodePosi(T)& x = BST<T>::search(e); if (x) return x; //确认目标不存在(留意对BST<T>::_hot的设置)
	x = new BinNode<T>(e, BST<T>::_hot, NULL, NULL, 0); BST<T>::_size++; //创建红节点x:以BST<T>::_hot为父,黑高度0
	BinNodePosi(T) xOld = x; solveDoubleRed(x); return xOld; //经双红修正后,即可返回
} //无论e是否存在于原树中,返回时总有x->data == e

2.2 删除函数

 //从红黑树中删除关键码e
template <typename T> bool RedBlack<T>::remove(const T& e) { 
	BinNodePosi(T)& x = BST<T>::search(e); if (!x) return false; //确认目标存在(留意BST<T>::_hot的设置)
	BinNodePosi(T) r = removeAt(x, BST<T>::_hot); if (!(--BST<T>::_size)) return true; //实施删除
 // assert: BST<T>::_hot某一孩子刚被删除,且被r所指节点(可能是NULL)接替。以下检查是否失衡,并做必要调整
	if (!BST<T>::_hot) //若刚被删除的是根节点,则将其置黑,并更新黑高度
	{
		BST<T>::_root->color = RB_BLACK; updateHeight(BST<T>::_root); return true;
	}
	// assert: 以下,原x(现r)必非根,BST<T>::_hot必非空
	if (BlackHeightUpdated(*BST<T>::_hot)) return true; //若所有祖先的黑深度依然平衡,则无需调整
	if (IsRed(r)) //否则,若r为红,则只需令其转黑
	{
		r->color = RB_BLACK; r->height++; return true;
	}
	// assert: 以下,原x(现r)均为黑色
	   //*DSA*/printBinTree(BST<T>::_hot, 0, 0);
	solveDoubleBlack(r); return true; //经双黑调整后返回
} //若目标节点存在且被删除,返回true;否则返回false

2.3 更新高度

//更新节点高度
template <typename T> int RedBlack<T>::updateHeight(BinNodePosi(T) x) { 
	return x->height = IsBlack(x) + max(stature(x->lc), stature(x->rc)); //孩子黑高度通常相等,除非出现双黑
	// 红黑树中各节点左、右孩子的黑高度通常相等
	// 这里之所以取更大值,是便于在删除节点后的平衡调整过程中,正确更新被删除节点父亲的黑高度
	// 否则,rotateAt()会根据被删除节点的替代者(高度小一)设置父节点的黑高度
}

2.4 双黑调整

/******************************************************************************************
 * RedBlack双黑调整算法:解决节点x与被其替代的节点均为黑色的问题
 * 分为三大类共四种情况:
 *    BB-1 :2次颜色翻转,2次黑高度更新,1~2次旋转,不再递归
 *    BB-2R:2次颜色翻转,2次黑高度更新,0次旋转,不再递归
 *    BB-2B:1次颜色翻转,1次黑高度更新,0次旋转,需要递归
 *    BB-3 :2次颜色翻转,2次黑高度更新,1次旋转,转为BB-1或BB2R
 ************************************************************************************
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值