Commons Collections学习笔记(三)

这个Map类是基于红黑树构建的,每个树节点有两个域,一个存放节点的Key,一个存放节点的Value,相当于是两棵红黑树,一棵是关于key的红黑树,一棵是关于Value的红黑树。

关于红黑树的详细介绍,参考《C#与数据结构--树论--红黑树(Red Black Tree)》这篇文章。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public final class DoubleOrderedMap extends AbstractMap
{
private Node[]rootNode = new Node[]{ null , null }; // 根节点

public SetentrySetByValue()
{
// 按Value获取Entry集合
if (setOfEntries[VALUE] == null ){
setOfEntries[VALUE]
= new AbstractSet(){
public Iteratoriterator(){
return new DoubleOrderedMapIterator(VALUE){
protected ObjectdoGetNext(){
return lastReturnedNode;
}
};
}
public boolean contains(Objecto){
if ( ! (o instanceof Map.Entry)){
return false ;
}
Map.Entryentry
= (Map.Entry)o;
Objectkey
= entry.getKey();
Nodenode
= lookup((Comparable)entry.getValue(),
VALUE);
return (node != null ) && node.getData(KEY).equals(key);
}
public boolean remove(Objecto){
if ( ! (o instanceof Map.Entry)){
return false ;
}
Map.Entryentry
= (Map.Entry)o;
Objectkey
= entry.getKey();
Nodenode
= lookup((Comparable)entry.getValue(),
VALUE);
if ((node != null ) && node.getData(KEY).equals(key)){
doRedBlackDelete(node);
return true ;
}
return false ;
}
public int size(){
return DoubleOrderedMap. this .size();
}
public void clear(){
DoubleOrderedMap.
this .clear();
}
};
}
return setOfEntries[VALUE];
}

private ObjectdoRemove( final Comparableo, final int index)
{
Nodenode
= lookup(o,index); // 在红黑树中查找节点
Objectrval = null ;
if (node != null )
{
rval
= node.getData(oppositeIndex(index));
doRedBlackDelete(node);
// 在红黑树中删除指定节点
}
return rval;
}
private ObjectdoGet( final Comparableo, final int index)
{
checkNonNullComparable(o,index);
// 检查参数非空
Nodenode = lookup(o,index); // 按Key或Value查找指定节点
return ((node == null ) ? null :node.getData(oppositeIndex(index)));
}
private Nodelookup( final Comparabledata, final int index)
{
Noderval
= null ;
Nodenode
= rootNode[index]; // 根节点
while (node != null )
{
int cmp = compare(data,node.getData(index)); // 与当前节点比较
if (cmp == 0 )
{
// 找到了
rval = node;
break ;
}
else { // 在左子树或右子树中寻找
node = (cmp < 0 )
? node.getLeft(index)
:node.getRight(index);
}
}
return rval;
}
private static NodeleastNode( final Nodenode, final int index)
{
// 返回指定节点的最右子节点
Noderval = node;
if (rval != null ){
while (rval.getLeft(index) != null ){
rval
= rval.getLeft(index);
}
}
return rval;
}

private NodenextGreater( final Nodenode, final int index)
{
// 返回下一个大于指定节点的节点
Noderval = null ;
if (node == null ){
rval
= null ;
}
else if (node.getRight(index) != null )
{
// 右子树不为空,返回右子树最左子节点
rval = leastNode(node.getRight(index),index);
}
else
{
// 不断向上,只要仍然是右子节点
Nodeparent = node.getParent(index);
Nodechild
= node;
while ((parent != null ) && (child == parent.getRight(index))){
child
= parent;
parent
= parent.getParent(index);
}
rval
= parent;
}
return rval;
}

private void rotateLeft( final Nodenode, final int index)
{
// 左旋操作
NoderightChild = node.getRight(index);
node.setRight(rightChild.getLeft(index),index);
if (rightChild.getLeft(index) != null ){
rightChild.getLeft(index).setParent(node,index);
}
rightChild.setParent(node.getParent(index),index);
if (node.getParent(index) == null )
{
// 设置为根节点
rootNode[index] = rightChild;
}
else if (node.getParent(index).getLeft(index) == node){
node.getParent(index).setLeft(rightChild,index);
}
else {
node.getParent(index).setRight(rightChild,index);
}
rightChild.setLeft(node,index);
node.setParent(rightChild,index);
}

private void rotateRight( final Nodenode, final int index)
{
// 右旋操作
NodeleftChild = node.getLeft(index);
node.setLeft(leftChild.getRight(index),index);
if (leftChild.getRight(index) != null ){
leftChild.getRight(index).setParent(node,index);
}
leftChild.setParent(node.getParent(index),index);
if (node.getParent(index) == null )
{
// 设置为根节点
rootNode[index] = leftChild;
}
else if (node.getParent(index).getRight(index) == node){
node.getParent(index).setRight(leftChild,index);
}
else {
node.getParent(index).setLeft(leftChild,index);
}
leftChild.setRight(node,index);
node.setParent(leftChild,index);
}
private void doRedBlackInsert( final NodeinsertedNode, final int index)
{
// 进行红黑树节点插入后的调整
NodecurrentNode = insertedNode; // 新插入节点置为当前节点
makeRed(currentNode,index); // 标记新节点为红色
while ((currentNode != null ) && (currentNode != rootNode[index]) && (isRed(currentNode.getParent(index),index)))
{
// 确保当前节点父节点为红色才继续处理
if (isLeftChild(getParent(currentNode,index),index))
{
// 父节点是祖父节点的左孩子
Nodey = getRightChild(getGrandParent(currentNode,index),index); // 叔节点是祖父节点的右孩子
if (isRed(y,index))
{
// 红叔(图4)
makeBlack(getParent(currentNode,index),index); // 标记父节点为黑色
makeBlack(y,index); // 标记叔节点为黑色
makeRed(getGrandParent(currentNode,index),index); // 标记祖父节点为红色
currentNode = getGrandParent(currentNode,index); // 置祖父节点为当前节点
}
else
{
// 黑叔(对应图5和图6)
if (isRightChild(currentNode,index))
{
// 当前节点是父节点的右孩子(图6)
currentNode = getParent(currentNode,index); // 置父节点为当前节点
rotateLeft(currentNode,index); // 左旋
}
makeBlack(getParent(currentNode,index),index);
// 当前节点的父节点置为黑色
makeRed(getGrandParent(currentNode,index),index); // 祖父节点置为红色
if (getGrandParent(currentNode,index) != null )
{
// 对祖父节点进行右旋
rotateRight(getGrandParent(currentNode,index),index);
}
}
}
else
{
// 父节点是祖父节点的右孩子
Nodey = getLeftChild(getGrandParent(currentNode,index),index); // 叔节点是祖父节点的左孩子
if (isRed(y,index))
{
// 红叔(图4)
makeBlack(getParent(currentNode,index),index); // 标记父节点为黑色
makeBlack(y,index); // 标记叔节点为黑色
makeRed(getGrandParent(currentNode,index),index); // 标记祖父节点为红色
currentNode = getGrandParent(currentNode,index); // 置祖父节点为当前节点
}
else
{
// 黑叔(对应图7和图8)
if (isLeftChild(currentNode,index))
{
// 当前节点是父节点的左孩子(图8)
currentNode = getParent(currentNode,index); // 置父节点为当前节点
rotateRight(currentNode,index); // 右旋
}
makeBlack(getParent(currentNode,index),index);
// 当前节点的父节点置为黑色
makeRed(getGrandParent(currentNode,index),index); // 祖父节点置为红色
if (getGrandParent(currentNode,index) != null )
{
// 对祖父节点进行左旋
rotateLeft(getGrandParent(currentNode,index),index);
}
}
}
}
makeBlack(rootNode[index],index);
// 标记根节点为黑色
}

private void doRedBlackDelete( final NodedeletedNode)
{
// 在红黑树中删除指定节点
for ( int index = FIRST_INDEX;index < NUMBER_OF_INDICES;index ++ ){
// ifdeletednodehasbothleftandchildren,swapwith
// thenextgreaternode
if ((deletedNode.getLeft(index) != null )
&& (deletedNode.getRight(index) != null )){
swapPosition(nextGreater(deletedNode,index),deletedNode,
index);
}
Nodereplacement
= ((deletedNode.getLeft(index) != null )
? deletedNode.getLeft(index)
:deletedNode.getRight(index));
if (replacement != null ){
replacement.setParent(deletedNode.getParent(index),index);

if (deletedNode.getParent(index) == null ){
rootNode[index]
= replacement;
}
else if (deletedNode
== deletedNode.getParent(index).getLeft(index)){
deletedNode.getParent(index).setLeft(replacement,index);
}
else {
deletedNode.getParent(index).setRight(replacement,index);
}
deletedNode.setLeft(
null ,index);
deletedNode.setRight(
null ,index);
deletedNode.setParent(
null ,index);
if (isBlack(deletedNode,index)){
doRedBlackDeleteFixup(replacement,index);
}
}
else {
// replacementisnull
if (deletedNode.getParent(index) == null ){
// emptytree
rootNode[index] = null ;
}
else {
// deletednodehadnochildren
if (isBlack(deletedNode,index)){
doRedBlackDeleteFixup(deletedNode,index);
}
if (deletedNode.getParent(index) != null ){
if (deletedNode
== deletedNode.getParent(index)
.getLeft(index)){
deletedNode.getParent(index).setLeft(
null ,index);
}
else {
deletedNode.getParent(index).setRight(
null ,
index);
}
deletedNode.setParent(
null ,index);
}
}
}
}
shrink();
}

private void doRedBlackDeleteFixup( final NodereplacementNode,
final int index)
{
// 重新局部平衡红黑树
NodecurrentNode = replacementNode;
while ((currentNode != rootNode[index])
&& (isBlack(currentNode,index))){
if (isLeftChild(currentNode,index)){
NodesiblingNode
=
getRightChild(getParent(currentNode,index),index);
if (isRed(siblingNode,index)){
makeBlack(siblingNode,index);
makeRed(getParent(currentNode,index),index);
rotateLeft(getParent(currentNode,index),index);
siblingNode
= getRightChild(getParent(currentNode,index),index);
}
if (isBlack(getLeftChild(siblingNode,index),index)
&& isBlack(getRightChild(siblingNode,index),
index)){
makeRed(siblingNode,index);
currentNode
= getParent(currentNode,index);
}
else {
if (isBlack(getRightChild(siblingNode,index),index)){
makeBlack(getLeftChild(siblingNode,index),index);
makeRed(siblingNode,index);
rotateRight(siblingNode,index);
siblingNode
=
getRightChild(getParent(currentNode,index),index);
}
copyColor(getParent(currentNode,index),siblingNode,
index);
makeBlack(getParent(currentNode,index),index);
makeBlack(getRightChild(siblingNode,index),index);
rotateLeft(getParent(currentNode,index),index);
currentNode
= rootNode[index];
}
}
else {
NodesiblingNode
= getLeftChild(getParent(currentNode,index),index);
if (isRed(siblingNode,index)){
makeBlack(siblingNode,index);
makeRed(getParent(currentNode,index),index);
rotateRight(getParent(currentNode,index),index);
siblingNode
= getLeftChild(getParent(currentNode,index),index);
}
if (isBlack(getRightChild(siblingNode,index),index)
&& isBlack(getLeftChild(siblingNode,index),index)){
makeRed(siblingNode,index);
currentNode
= getParent(currentNode,index);
}
else {
if (isBlack(getLeftChild(siblingNode,index),index)){
makeBlack(getRightChild(siblingNode,index),index);
makeRed(siblingNode,index);
rotateLeft(siblingNode,index);
siblingNode
=
getLeftChild(getParent(currentNode,index),index);
}
copyColor(getParent(currentNode,index),siblingNode,
index);
makeBlack(getParent(currentNode,index),index);
makeBlack(getLeftChild(siblingNode,index),index);
rotateRight(getParent(currentNode,index),index);
currentNode
= rootNode[index];
}
}
}
makeBlack(currentNode,index);
}
private void swapPosition( final Nodex, final Nodey, final int index)
{
// 交换树中两个节点
// Saveinitialvalues.
NodexFormerParent = x.getParent(index);
NodexFormerLeftChild
= x.getLeft(index);
NodexFormerRightChild
= x.getRight(index);
NodeyFormerParent
= y.getParent(index);
NodeyFormerLeftChild
= y.getLeft(index);
NodeyFormerRightChild
= y.getRight(index);
boolean xWasLeftChild =
(x.getParent(index)
!= null )
&& (x == x.getParent(index).getLeft(index));
boolean yWasLeftChild =
(y.getParent(index)
!= null )
&& (y == y.getParent(index).getLeft(index));
// Swap,handlingspecialcasesofonebeingtheother'sparent.
if (x == yFormerParent){ // xwasy'sparent
x.setParent(y,index);
if (yWasLeftChild){
y.setLeft(x,index);
y.setRight(xFormerRightChild,index);
}
else {
y.setRight(x,index);
y.setLeft(xFormerLeftChild,index);
}
}
else {
x.setParent(yFormerParent,index);
if (yFormerParent != null ){
if (yWasLeftChild){
yFormerParent.setLeft(x,index);
}
else {
yFormerParent.setRight(x,index);
}
}
y.setLeft(xFormerLeftChild,index);
y.setRight(xFormerRightChild,index);
}
if (y == xFormerParent){ // ywasx'sparent
y.setParent(x,index);
if (xWasLeftChild){
x.setLeft(y,index);
x.setRight(yFormerRightChild,index);
}
else {
x.setRight(y,index);
x.setLeft(yFormerLeftChild,index);
}
}
else {
y.setParent(xFormerParent,index);
if (xFormerParent != null ){
if (xWasLeftChild){
xFormerParent.setLeft(y,index);
}
else {
xFormerParent.setRight(y,index);
}
}
x.setLeft(yFormerLeftChild,index);
x.setRight(yFormerRightChild,index);
}
// Fixchildren'sparentpointers
if (x.getLeft(index) != null ){
x.getLeft(index).setParent(x,index);
}
if (x.getRight(index) != null ){
x.getRight(index).setParent(x,index);
}
if (y.getLeft(index) != null ){
y.getLeft(index).setParent(y,index);
}
if (y.getRight(index) != null ){
y.getRight(index).setParent(y,index);
}
x.swapColors(y,index);
// Checkifrootchanged
if (rootNode[index] == x){
rootNode[index]
= y;
}
else if (rootNode[index] == y){
rootNode[index]
= x;
}
}
public Objectput( final Objectkey, final Objectvalue)
throws ClassCastException,NullPointerException,
IllegalArgumentException{
checkKeyAndValue(key,value);
Nodenode
= rootNode[KEY];
if (node == null ){ // 空树
Noderoot = new Node((Comparable)key,(Comparable)value);
rootNode[KEY]
= root;
rootNode[VALUE]
= root;
grow();
}
else {
while ( true ){
int cmp = compare((Comparable)key,node.getData(KEY));
if (cmp == 0 ){
throw new IllegalArgumentException(
" Cannotstoreaduplicatekey(/ "" +key
+ " / " )in this Map " );
} else if (cmp < 0 ){
if (node.getLeft(KEY) != null ){
node
= node.getLeft(KEY);
}
else {
NodenewNode
= new Node((Comparable)key,
(Comparable)value);
insertValue(newNode);
node.setLeft(newNode,KEY);
newNode.setParent(node,KEY);
doRedBlackInsert(newNode,KEY);
grow();
break ;
}
}
else { // cmp>0
if (node.getRight(KEY) != null ){
node
= node.getRight(KEY);
}
else {
NodenewNode
= new Node((Comparable)key,
(Comparable)value);
insertValue(newNode);
node.setRight(newNode,KEY);
newNode.setParent(node,KEY);
doRedBlackInsert(newNode,KEY);
grow();
break ;
}
}
}
}
return null ;
}
private abstract class DoubleOrderedMapIterator implements Iterator
{
private int expectedModifications;
protected NodelastReturnedNode; // 上次访问的节点
private NodenextNode; // 下一个节点(最左子节点)
private int iteratorType;
DoubleOrderedMapIterator(
final int type)
{
iteratorType
= type;
expectedModifications
= DoubleOrderedMap. this .modifications;
lastReturnedNode
= null ;
nextNode
= leastNode(rootNode[iteratorType],
iteratorType);
}
protected abstract ObjectdoGetNext();
public final boolean hasNext(){
return nextNode != null ;
}
public final Objectnext()
throws NoSuchElementException,
ConcurrentModificationException{
if (nextNode == null ){
throw new NoSuchElementException();
}
if (modifications != expectedModifications){
throw new ConcurrentModificationException();
}
lastReturnedNode
= nextNode;
nextNode
= nextGreater(nextNode,iteratorType);
return doGetNext();
}
public final void remove()
throws IllegalStateException,
ConcurrentModificationException{
if (lastReturnedNode == null ){
throw new IllegalStateException();
}
if (modifications != expectedModifications){
throw new ConcurrentModificationException();
}
doRedBlackDelete(lastReturnedNode);
expectedModifications
++ ;
lastReturnedNode
= null ;
}
}

// 内部节点类
private static final class Node implements Map.Entry,KeyValue
{
private Comparable[]data; // 数据域(key和value)
private Node[]leftNode; // 左子节点
private Node[]rightNode; // 右子节点
private Node[]parentNode; // 父节点
private boolean []blackColor; // 颜色(红或黑)
}
}




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值