Blame qtools/qmap.cpp

Packit Service 50c9f2
/****************************************************************************
Packit Service 50c9f2
** 
Packit Service 50c9f2
**
Packit Service 50c9f2
** Implementation of QMap
Packit Service 50c9f2
**
Packit Service 50c9f2
** Created : 990406
Packit Service 50c9f2
**
Packit Service 50c9f2
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is part of the tools module of the Qt GUI Toolkit.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed under the terms of the Q Public License
Packit Service 50c9f2
** as defined by Trolltech AS of Norway and appearing in the file
Packit Service 50c9f2
** LICENSE.QPL included in the packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed and/or modified under the terms of the
Packit Service 50c9f2
** GNU General Public License version 2 as published by the Free Software
Packit Service 50c9f2
** Foundation and appearing in the file LICENSE.GPL included in the
Packit Service 50c9f2
** packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
Packit Service 50c9f2
** licenses may use this file in accordance with the Qt Commercial License
Packit Service 50c9f2
** Agreement provided with the Software.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
Packit Service 50c9f2
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Packit Service 50c9f2
**
Packit Service 50c9f2
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
Packit Service 50c9f2
**   information about Qt Commercial License Agreements.
Packit Service 50c9f2
** See http://www.trolltech.com/qpl/ for QPL licensing information.
Packit Service 50c9f2
** See http://www.trolltech.com/gpl/ for GPL licensing information.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Contact info@trolltech.com if any conditions of this licensing are
Packit Service 50c9f2
** not clear to you.
Packit Service 50c9f2
**
Packit Service 50c9f2
**********************************************************************/
Packit Service 50c9f2
Packit Service 50c9f2
#include "qmap.h"
Packit Service 50c9f2
Packit Service 50c9f2
typedef QMapNodeBase* NodePtr;
Packit Service 50c9f2
typedef QMapNodeBase Node;
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
void QMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
Packit Service 50c9f2
{
Packit Service 50c9f2
    NodePtr y = x->right;
Packit Service 50c9f2
    x->right = y->left;
Packit Service 50c9f2
    if (y->left !=0)
Packit Service 50c9f2
	y->left->parent = x;
Packit Service 50c9f2
    y->parent = x->parent;
Packit Service 50c9f2
    if (x == root)
Packit Service 50c9f2
	root = y;
Packit Service 50c9f2
    else if (x == x->parent->left)
Packit Service 50c9f2
	x->parent->left = y;
Packit Service 50c9f2
    else
Packit Service 50c9f2
	x->parent->right = y;
Packit Service 50c9f2
    y->left = x;
Packit Service 50c9f2
    x->parent = y;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
void QMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
Packit Service 50c9f2
{
Packit Service 50c9f2
    NodePtr y = x->left;
Packit Service 50c9f2
    x->left = y->right;
Packit Service 50c9f2
    if (y->right != 0)
Packit Service 50c9f2
	y->right->parent = x;
Packit Service 50c9f2
    y->parent = x->parent;
Packit Service 50c9f2
    if (x == root)
Packit Service 50c9f2
	root = y;
Packit Service 50c9f2
    else if (x == x->parent->right)
Packit Service 50c9f2
	x->parent->right = y;
Packit Service 50c9f2
    else
Packit Service 50c9f2
	x->parent->left = y;
Packit Service 50c9f2
    y->right = x;
Packit Service 50c9f2
    x->parent = y;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
void QMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
Packit Service 50c9f2
{
Packit Service 50c9f2
    x->color = Node::Red;
Packit Service 50c9f2
    while ( x != root && x->parent->color == Node::Red ) {
Packit Service 50c9f2
	if ( x->parent == x->parent->parent->left ) {
Packit Service 50c9f2
	    NodePtr y = x->parent->parent->right;
Packit Service 50c9f2
	    if (y && y->color == Node::Red) {
Packit Service 50c9f2
		x->parent->color = Node::Black;
Packit Service 50c9f2
		y->color = Node::Black;
Packit Service 50c9f2
		x->parent->parent->color = Node::Red;
Packit Service 50c9f2
		x = x->parent->parent;
Packit Service 50c9f2
	    } else {
Packit Service 50c9f2
		if (x == x->parent->right) {
Packit Service 50c9f2
		    x = x->parent;
Packit Service 50c9f2
		    rotateLeft( x, root );
Packit Service 50c9f2
		}
Packit Service 50c9f2
		x->parent->color = Node::Black;
Packit Service 50c9f2
		x->parent->parent->color = Node::Red;
Packit Service 50c9f2
		rotateRight (x->parent->parent, root );
Packit Service 50c9f2
	    }
Packit Service 50c9f2
	} else {
Packit Service 50c9f2
	    NodePtr y = x->parent->parent->left;
Packit Service 50c9f2
	    if ( y && y->color == Node::Red ) {
Packit Service 50c9f2
		x->parent->color = Node::Black;
Packit Service 50c9f2
		y->color = Node::Black;
Packit Service 50c9f2
		x->parent->parent->color = Node::Red;
Packit Service 50c9f2
		x = x->parent->parent;
Packit Service 50c9f2
	    } else {
Packit Service 50c9f2
		if (x == x->parent->left) { 
Packit Service 50c9f2
		    x = x->parent;
Packit Service 50c9f2
		    rotateRight( x, root );
Packit Service 50c9f2
		}
Packit Service 50c9f2
		x->parent->color = Node::Black;
Packit Service 50c9f2
		x->parent->parent->color = Node::Red;
Packit Service 50c9f2
		rotateLeft( x->parent->parent, root );
Packit Service 50c9f2
	    }
Packit Service 50c9f2
	}
Packit Service 50c9f2
    }
Packit Service 50c9f2
    root->color = Node::Black;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
Packit Service 50c9f2
NodePtr QMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
Packit Service 50c9f2
					     NodePtr& leftmost,
Packit Service 50c9f2
					     NodePtr& rightmost )
Packit Service 50c9f2
{
Packit Service 50c9f2
    NodePtr y = z;
Packit Service 50c9f2
    NodePtr x;
Packit Service 50c9f2
    NodePtr x_parent;
Packit Service 50c9f2
    if (y->left == 0) {
Packit Service 50c9f2
	x = y->right;
Packit Service 50c9f2
    } else {
Packit Service 50c9f2
	if (y->right == 0)
Packit Service 50c9f2
	    x = y->left;
Packit Service 50c9f2
	else
Packit Service 50c9f2
	    {
Packit Service 50c9f2
		y = y->right;
Packit Service 50c9f2
		while (y->left != 0)
Packit Service 50c9f2
		    y = y->left;
Packit Service 50c9f2
		x = y->right;
Packit Service 50c9f2
	    }
Packit Service 50c9f2
    }
Packit Service 50c9f2
    if (y != z) {
Packit Service 50c9f2
	z->left->parent = y; 
Packit Service 50c9f2
	y->left = z->left;
Packit Service 50c9f2
	if (y != z->right) {
Packit Service 50c9f2
	    x_parent = y->parent;
Packit Service 50c9f2
	    if (x)
Packit Service 50c9f2
		x->parent = y->parent;
Packit Service 50c9f2
	    y->parent->left = x;
Packit Service 50c9f2
	    y->right = z->right;
Packit Service 50c9f2
	    z->right->parent = y;
Packit Service 50c9f2
	} else {
Packit Service 50c9f2
	    x_parent = y;  
Packit Service 50c9f2
	}
Packit Service 50c9f2
	if (root == z)
Packit Service 50c9f2
	    root = y;
Packit Service 50c9f2
	else if (z->parent->left == z)
Packit Service 50c9f2
	    z->parent->left = y;
Packit Service 50c9f2
	else 
Packit Service 50c9f2
	    z->parent->right = y;
Packit Service 50c9f2
	y->parent = z->parent;
Packit Service 50c9f2
	// Swap the colors
Packit Service 50c9f2
	Node::Color c = y->color;
Packit Service 50c9f2
	y->color = z->color;
Packit Service 50c9f2
	z->color = c;
Packit Service 50c9f2
	y = z;
Packit Service 50c9f2
    } else {       
Packit Service 50c9f2
	x_parent = y->parent;
Packit Service 50c9f2
	if (x)
Packit Service 50c9f2
	    x->parent = y->parent;   
Packit Service 50c9f2
	if (root == z)
Packit Service 50c9f2
	    root = x;
Packit Service 50c9f2
	else if (z->parent->left == z)
Packit Service 50c9f2
	    z->parent->left = x;
Packit Service 50c9f2
	else
Packit Service 50c9f2
	    z->parent->right = x;
Packit Service 50c9f2
	if ( leftmost == z ) {
Packit Service 50c9f2
	    if (z->right == 0)
Packit Service 50c9f2
		leftmost = z->parent;
Packit Service 50c9f2
	    else
Packit Service 50c9f2
		leftmost = x->minimum();
Packit Service 50c9f2
	}
Packit Service 50c9f2
	if (rightmost == z) {
Packit Service 50c9f2
	    if (z->left == 0)
Packit Service 50c9f2
		rightmost = z->parent;  
Packit Service 50c9f2
	    else
Packit Service 50c9f2
		rightmost = x->maximum();
Packit Service 50c9f2
	}
Packit Service 50c9f2
    }
Packit Service 50c9f2
    if (y->color != Node::Red) { 
Packit Service 50c9f2
	while (x != root && (x == 0 || x->color == Node::Black)) {
Packit Service 50c9f2
	    if (x == x_parent->left) {
Packit Service 50c9f2
		NodePtr w = x_parent->right;
Packit Service 50c9f2
		if (w->color == Node::Red) {
Packit Service 50c9f2
		    w->color = Node::Black;
Packit Service 50c9f2
		    x_parent->color = Node::Red;
Packit Service 50c9f2
		    rotateLeft(x_parent, root);
Packit Service 50c9f2
		    w = x_parent->right;
Packit Service 50c9f2
		}
Packit Service 50c9f2
		if ((w->left == 0 || w->left->color == Node::Black) &&
Packit Service 50c9f2
		    (w->right == 0 || w->right->color == Node::Black)) {
Packit Service 50c9f2
		    w->color = Node::Red;
Packit Service 50c9f2
		    x = x_parent;
Packit Service 50c9f2
		    x_parent = x_parent->parent;
Packit Service 50c9f2
		} else {
Packit Service 50c9f2
		    if (w->right == 0 || w->right->color == Node::Black) {
Packit Service 50c9f2
			if (w->left)
Packit Service 50c9f2
			    w->left->color = Node::Black;
Packit Service 50c9f2
			w->color = Node::Red;
Packit Service 50c9f2
			rotateRight(w, root);
Packit Service 50c9f2
			w = x_parent->right;
Packit Service 50c9f2
		    }
Packit Service 50c9f2
		    w->color = x_parent->color;
Packit Service 50c9f2
		    x_parent->color = Node::Black;
Packit Service 50c9f2
		    if (w->right)
Packit Service 50c9f2
			w->right->color = Node::Black;
Packit Service 50c9f2
		    rotateLeft(x_parent, root);
Packit Service 50c9f2
		    break;
Packit Service 50c9f2
		}
Packit Service 50c9f2
	    } else {
Packit Service 50c9f2
		NodePtr w = x_parent->left;
Packit Service 50c9f2
		if (w->color == Node::Red) {
Packit Service 50c9f2
		    w->color = Node::Black;
Packit Service 50c9f2
		    x_parent->color = Node::Red;
Packit Service 50c9f2
		    rotateRight(x_parent, root);
Packit Service 50c9f2
		    w = x_parent->left;
Packit Service 50c9f2
		}
Packit Service 50c9f2
		if ((w->right == 0 || w->right->color == Node::Black) &&
Packit Service 50c9f2
		    (w->left == 0 || w->left->color == Node::Black)) {
Packit Service 50c9f2
		    w->color = Node::Red;
Packit Service 50c9f2
		    x = x_parent;
Packit Service 50c9f2
		    x_parent = x_parent->parent;
Packit Service 50c9f2
		} else {
Packit Service 50c9f2
		    if (w->left == 0 || w->left->color == Node::Black) {
Packit Service 50c9f2
			if (w->right) 
Packit Service 50c9f2
			    w->right->color = Node::Black;
Packit Service 50c9f2
			w->color = Node::Red;
Packit Service 50c9f2
			rotateLeft(w, root);
Packit Service 50c9f2
			w = x_parent->left;
Packit Service 50c9f2
		    }
Packit Service 50c9f2
		    w->color = x_parent->color;
Packit Service 50c9f2
		    x_parent->color = Node::Black;
Packit Service 50c9f2
		    if (w->left)
Packit Service 50c9f2
			w->left->color = Node::Black;
Packit Service 50c9f2
		    rotateRight(x_parent, root);
Packit Service 50c9f2
		    break;
Packit Service 50c9f2
		}
Packit Service 50c9f2
	    }
Packit Service 50c9f2
	}
Packit Service 50c9f2
	if (x)
Packit Service 50c9f2
	    x->color = Node::Black;
Packit Service 50c9f2
    }
Packit Service 50c9f2
    return y;
Packit Service 50c9f2
}