中国科技大学算法导论第二次实验报告.docx

上传人:b****5 文档编号:3204176 上传时间:2022-11-20 格式:DOCX 页数:15 大小:38.59KB
下载 相关 举报
中国科技大学算法导论第二次实验报告.docx_第1页
第1页 / 共15页
中国科技大学算法导论第二次实验报告.docx_第2页
第2页 / 共15页
中国科技大学算法导论第二次实验报告.docx_第3页
第3页 / 共15页
中国科技大学算法导论第二次实验报告.docx_第4页
第4页 / 共15页
中国科技大学算法导论第二次实验报告.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

中国科技大学算法导论第二次实验报告.docx

《中国科技大学算法导论第二次实验报告.docx》由会员分享,可在线阅读,更多相关《中国科技大学算法导论第二次实验报告.docx(15页珍藏版)》请在冰豆网上搜索。

中国科技大学算法导论第二次实验报告.docx

中国科技大学算法导论第二次实验报告

第二次实验报告红黑树

1.红黑树

1.1需求分析

本实验要求实现红黑树各种操作如SEARCH,PREDECESOR,SUCCESSOR,

MINIMUM,MAXIMUM,INSERT,DELETE等。

红黑树是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途

是实现关联数组。

它是在1972年由RudolfBayer发明的,他称之为"对称二叉B树",它现

代的名字是在LeoJ.Guibas和RobertSedgewick于1978年写的一篇论文中获得的。

它是

复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的:

它可以在O(log

n)时间内做查找,插入和删除,这里的n是树中元素的数目。

红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。

在二叉查找树强

制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

1.每个结点或红或黑。

2.根结点为黑色。

3.每个叶结点(实际上就是NULL指针)都是黑色的。

4.如果一个结点是红色的,那么它的周边3个节点都是黑色的。

5.对于每个结点,从该结点到其所有子孙叶结点的路径中所包含的黑色结点个数都一

样。

这些约束强制了红黑树的关键性质:

从根到叶子的最长的可能路径不多于最短的可能

路径的两倍长。

结果是这个树大致上是平衡的。

因为操作比如插入、删除和查找某个值的最

坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都

是高效的,而不同于普通的二叉查找树。

要知道为什么这些特性确保了这个结果,注意到属性5导致了路径不能有两个毗连的红

色节点就足够了。

最短的可能路径都是黑色节点,最长的可能路径有交替的红色和黑色节点。

因为根据属性4所有最长的路径都有相同数目的黑色节点,这就表明了没有路径能多于任何其他路径的两倍长。

在很多树数据结构的表示中,一个节点有可能只有一个子节点,而叶子节点包含数据。

用这种范例表示红黑树是可能的,但是这会改变一些属性并使算法复杂。

为此,本文中我们使用"nil叶子"或"空(null)叶子"。

1.2算法设计

操作SEARCH,,PREDECESOR,SUCCESSOR,MINIMUM,MAXIMUM与二查检索

树的对应操作几乎相同。

这里只介绍旋转、插入、删除。

1.2.1旋转

由于插入、删除操作对树作了修改,结果可能违反红黑树的五个性质。

为保持这些性质,

就要改变树中某些结点的颜色以及指针结构。

指针结构的修改通过旋转来完成。

当在某个结点x上做左旋时,假设它的有孩子y不是nil[T],左旋以x与y之间的链为

“支轴”进行。

它使y成为该子树新的根,x成为y的左孩子,而y的左孩子成为x的孩

子。

右旋与左旋对称。

左旋代码如下:

voidRBLeftRotate(RBTree*T,RBTreeNode*x)

{

RBTreeNode*y=x->right;

x->right=y->left;

if(y->left!

=T->NIL)

y->left->parent=x;

y->parent=x->parent;

if(x->parent==T->NIL)

T->root=y;

elseif(x->parent->left==x)

x->parent->left=y;

else

x->parent->right=y;

y->left=x;

x->parent=y;

}

1.2.2插入

向一颗含n个结点的红黑树插入一个结点z的操作可在O(lgn)时间完成。

利用二叉查找

树的Tree_Insert过程,将z插入树内,并将其着红色。

为保证红黑树的性质,调用

RB_INSERTT_FIXUP来对结点重新着色并旋转。

RB_INSERTT_FIXUP代码如下:

voidRBTreeInsertFixup(RBTree*T,RBTreeNode*z)

{

RBTreeNode*y;

if(z->parent==T->NIL)//z是根节点

{

z->color=BLACK;

return;

}

if(z->parent->color==BLACK)//这种情况下是平衡的

{

return;

}

//一直循环,直到z的父节点的颜色为黑色

while(z->parent->color==RED)

{

if(z->parent==z->parent->parent->left)//当z的父节点是z祖父节点的左孩子时

{

y=z->parent->parent->right;//y是z的叔叔

//case1:

z的叔叔y的颜色为红色

if(y->color==RED)

{

z->parent->color=BLACK;

y->color=BLACK;

z->parent->parent->color=RED;

z=z->parent->parent;

}

else

{

if(z==z->parent->right)//case2:

z的叔叔y的颜色为黑色并且z是它父节点的右孩子

{

z=z->parent;

RBLeftRotate(T,z);

}

//case3:

z的叔叔y的颜色为黑色并且z是它父节点的左孩子

z->parent->color=BLACK;

z->parent->parent->color=RED;

RBRightRotate(T,z->parent->parent);

}

}//当z的父节点是z祖父节点的右孩子时

else//如果z的父节点是其祖父节点的右孩子

{

y=z->parent->parent->left;//y是z的叔叔节点

if(y->color==RED)//case1:

z的叔叔节点为红色,则z的父节点BLACK,祖父节点RED,叔叔节点BLACK均变色

{

z->parent->color=BLACK;

y->color=BLACK;

z->parent->parent->color=RED;

z=z->parent->parent;

}

else

{

if(z==z->parent->left)//case2:

z的叔叔y的颜色为黑色并且z是它父节点的左孩子

{

z=z->parent;

RBRightRotate(T,z);

}

//case3:

z的叔叔y的颜色为黑色并且z是它父节点的右孩子

z->parent->color=BLACK;

z->parent->parent->color=RED;

RBLeftRotate(T,z->parent->parent);

}

}

}

T->root->color=BLACK;

}

当调用RB_INSERTT_FIXUP(T,z)时,while有三种情况:

Case1):

z的叔叔y是红色

只有在p[z]和y都是红色的时候才会执行case1。

既然p[p[z]]是黑色的,可以将p[z]和

y都着黑色,再将p[p[z]]着红色保持性质5,然后z=p[p[z]]来重复while循环。

Case2):

z的叔叔y是黑色,且z的为p[z]的右孩子

Case3):

z的叔叔y是黑色,且z的为p[z]的左孩子

Case2与case3如上图。

Case2中z是p[z]的右孩子,利用左旋把case2转化为case3,

因为z与p[z]都是红色的,左旋对结点黑高度和性质5每影响。

在case3下可以通过改颜

色和旋转的方式到达平衡,并且不再出现红色警戒,因为无需往上遍历。

首先我们将红父

变成黑色,祖父变成红色,然后对祖父进行右旋转。

这样我们可以看到,整颗树的黑高

-4-

不变,并且这颗树的左右子树也达到平衡。

新的树根为黑色。

 

1.3结果分析

根据每次从文件中读的数据,调用RB_Insert()。

理论上红黑树结构应为下图,

由实验运行结果知,程序是正确的。

 

/*

*copyright@nciaebupt转载请保留此标记

*所有代码已经在linuxg++下编译通过,直接拷贝运行即可如有问题欢迎指正

*红黑树(red-blacktree)是许多“平衡的”查找树中的一种。

*红黑树的性质:

*1、每个结点或是红的,或是黑的。

*2、根结点是黑的。

*3、每个叶结点(NIL)是黑的。

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

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

*红黑树的结点比普通的二叉查找树的结点多了一个颜色属性。

*/

#include

#include

usingnamespacestd;

//将RED,BLACK颜色值定义成枚举类型

enumRBCOLOR{RED,BLACK};

//定义红黑树节点的数据结构

structRBTreeNode

{

intkey;

RBCOLORcolor;

RBTreeNode*left;

RBTreeNode*right;

RBTreeNode*parent;

};

//定义红黑树的数据结构

structRBTree

{

RBTreeNode*root;

RBTreeNode*NIL;

};

voidRBTreeInsertFixup(RBTree*T,RBTreeNode*z);

//实现红黑树的左旋操作

voidRBLeftRotate(RBTree*T,RBTreeNode*x)

{

RBTreeNode*y=x->right;

x->right=y->left;

if(y->left!

=T->NIL)

y->left->parent=x;

y->parent=x->parent;

if(x->parent==T->NIL)

T->root=y;

elseif(x->parent->left==x)

x->parent->left=y;

else

x->parent->right=y;

y->left=x;

x->parent=y;

}

 

//实现红黑树的右旋操作

voidRBRightRotate(RBTree*T,RBTreeNode*x)

{

RBTreeNode*y=x->left;

if(x->left==T->NIL)

return;

x->left=y->right;

if(y->right!

=T->NIL)

{

y->right->parent=x

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 唐诗宋词

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1