个人关于红黑树的理解

目录

 

红黑树(red-black-tree)

一.红黑树的定义和性质

二.红黑树的结构

三.输出一颗红黑树

四.查询红黑树

查找

查找最大关键字元素和最小关键字元素

查找前驱和后继

五.※插入和删除

插入

删除

六.完整代码


红黑树(red-black-tree)

一.红黑树的定义和性质

红黑树是一种二叉查找树,在每个结点上增加一个存储位表示结点的颜色,,可以是red或者是black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树保证没有一条路径会比其他路径长出两倍,因而是接近平衡的。可以证明,一颗有n个点内结点的红黑树的高度至多为2lg(n+1).

一颗红黑树应满足以下性质:

1.每个结点是红的或者是黑的

2.根结点是黑的

3.每个叶结点(NIL)是黑的

4.如果一个结点是红的,则它的两个儿子都是黑的

5.对于每个结点,从该结点到其他子孙结点的所有路径上包含相同数目的黑结点

                                      

                                                                   (省略叶节点NIL)

二.红黑树的结构

树中的每个结点包括color,key,left,right,fa,分别表示结点的颜色,值,左儿子,右儿子,父结点。如果某结点没有一个子结点或者父结点,则该结点的相应指针指向NULL,这里定义一个哨兵表示NULL.

struct RB_Node{   //树结点
	int key;
	bool color;
	RB_Node *fa, *left, *right;
};
struct RB_tree{  //红黑树(red-black-tree)
	RB_Node* root;  //红黑树的根结点
	RB_Node* NIL;   //红黑树的叶节点(哨兵)
	RB_tree(){
		NIL = new RB_Node();
		NIL->color = black;
		root = NIL;
	}
	void RB_inorder(RB_Node* x);   //中序遍历输出一颗红黑树
	void RB_printf(RB_Node* x, int n = 0);   //逆时90度输出一颗红黑树
	RB_Node* RB_search(RB_Node* x, int k);  //查找key值为k的树结点
	RB_Node* RB_minnum(RB_Node* x);   //查找以x为根结点的树的最小值
	RB_Node* RB_maxnum(RB_Node* x);   //查找以x为根结点的树的最大值
	RB_Node* RB_successor(RB_Node* x);  //查找x的后继结点
	RB_Node* RB_precursor(RB_Node* x);  //查找x的前驱结点
	void RB_left_rotate(RB_Node* x);    //左旋
	void RB_right_rotate(RB_Node* x);   //右旋
	void RB_insert(RB_Node* x);      //插入新的树结点
	RB_Node* RB_delete(RB_Node* x);   //删除树结点
	void RB_insert_fixup(RB_Node *x);  //插入结点后,调整红黑树的结构保持红黑树的性质
	void RB_delete_fixup(RB_Node *x);  //删除结点后,调整红黑树的结构保持红黑树的性质
}T;

三.输出一颗红黑树

1.可以用中序遍历的方式按照排序顺序输出树中的关键字,设x是树结点的某一点,则中序遍历是先输出x的左子树,再输出x结点的值,然后再输出x的右子树

2.有时候按照顺序排序输出一颗红黑树并不能非常直观的看出树的结点之间的关系,可以用稍微修改后的中序遍历方法,逆时针90度输出一颗二叉树。

void RB_tree::RB_inorder(RB_Node *x){  //中序遍历输出一颗红黑树
	if (x != NIL){
		RB_inorder(x->left);
		printf("%d ", x->key);
		RB_inorder(x->right);
	}
}
void RB_tree::RB_printf(RB_Node *x, int n){  //逆时90度输出一颗红黑树
	if (x == NIL){
		for (int i = 0; i<n; i++){
			printf("     ");
		}
		printf("NIL\n");
		return;
	}
	RB_printf(x->right, n + 1);	//输出右子树
	for (int i = 0; i<n; i++){	//输出长为n的"     "空格
		printf("     ");
	}
	if (n >= 0){
		printf("%d%c-->\n", x->key,x->color?'b':'r');   // 输出该点的数值
	}
	RB_printf(x->left, n + 1);	//输出左子树
}

                                                         

四.查询红黑树

对于红黑树的性质来说,这查找,查找最大值,前驱后继的过程的时间复杂度都是O(lg(n)),n为树结点个数。

查找

对于红黑树,最常用的操作就是查找树中的一个关键字了。给定指定树根的指针和关键字k,通过函数RB_search返回包含关键字k的结点的指针,不存在则返回NIL

RB_Node* RB_tree::RB_search(RB_Node *x, int k){
	if (x == NIL || k == x->key)
		return x;
	if (k < x->key)
		return RB_search(x->left, k);
	else
		return RB_search(x->right, k);
}

查找最大关键字元素和最小关键字元素

    利用红黑树原本就是一颗二叉查找树的构造的性质,要查找二叉树中具有最小关键字的元素,只要从根结点开始,沿着各结点的left指针查找下去,知道遇到NIL时为止;查找二叉树的具有最大关键字的元素的方法和它对称相反。

RB_Node* RB_tree::RB_minnum(RB_Node* x){
	while (x->left != NIL)
		x = x->left;
	return x;
}
RB_Node* RB_tree::RB_maxnum(RB_Node* x){
	while (x->right != NIL)
		x = x->right;
	return x;
}

查找前驱和后继

     如果所有的关键字均不相同,则某一结点x的后继既是具有大于key[x]中的关键字中最小值的那个结点;某一结点x的前驱既是具有小于key[x]中的关键字中最大值的那个结点。
     根据二叉搜索树的结构,不用对关键字做任何比较,就可以找出某个结点的前驱和后继。 
     如果二叉搜索树中某个结点有两个儿子,则其后继没有左儿子,其前驱没有右儿子。
 

RB_Node* RB_tree::RB_
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
红黑树是一种自平衡的二叉搜索树,它具有高效的查找、插入和删除操作。为了帮助理解红黑树的结构和操作,可以通过在线演示工具来展示红黑树的操作过程。 红黑树在线演示exe是一种基于图形界面的应用程序,它提供了一个可视化的界面来展示红黑树的构建和变化过程。通过这个应用程序,我们可以看到红黑树在不同操作下的结构变化,更好地理解红黑树的性质和操作规则。 在红黑树在线演示exe中,我们可以通过一系列的操作来创建、插入、删除和搜索红黑树节点。通过点击按钮或者键入相应的命令,我们可以执行这些操作并观察红黑树的变化。在每一步操作后,程序会自动重新绘制红黑树的结构,以便我们可以清晰地看到每个节点和链接的颜色变化。 通过红黑树在线演示exe,我们可以更加直观地理解红黑树的性质和操作规则,例如红黑树节点的颜色、红黑树充满性质等。同时,通过与实际的红黑树操作配合使用,我们可以更好地掌握红黑树的使用和应用。 红黑树在线演示exe是一种有助于学习红黑树的工具,它可以帮助我们通过可视化的方式更好地理解和掌握红黑树的结构和操作。不仅可以用于个人的学习和研究,也可以用于教学和示范目的。希望通过红黑树在线演示exe,大家能够更深入地理解红黑树的原理和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值