blob: 15c28101ef0b83fca26bf34f570a10c5481de048 [file] [log] [blame]
/****
Copyright (C) 1996 McGill University.
Copyright (C) 1996 McCAT System Group.
Copyright (C) 1996 ACAPS Benchmark Administrator
benadmin@acaps.cs.mcgill.ca
This program is free software; you can redistribute it and/or modify
it provided this copyright notice is maintained.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
****/
#include <stdio.h>
#include <stdlib.h>
#include "struktur.h"
#include "headers.h"
CHsplay_node *CHfind(CHsplay_node *root, key key)
{
if (((root->element.key.radius < key.radius) ||
((root->element.key.radius == key.radius) &&
(root->element.key.angle > key.angle)) ||
((root->element.key.radius == key.radius) &&
(root->element.key.angle == key.angle) &&
(root->element.key.number < key.number))) &&
(root->right != NULL))
return CHfind(root->right,key);
else if (((root->element.key.radius > key.radius) ||
((root->element.key.radius == key.radius) &&
(root->element.key.angle < key.angle)) ||
((root->element.key.radius == key.radius) &&
(root->element.key.angle == key.angle) &&
(root->element.key.number > key.number))) &&
(root->left != NULL))
return CHfind(root->left,key);
else
return root;
}
/*
if ((root->element.key.radius < key.radius) && (root->right != NULL))
return CHfind(root->right,key);
else if ((root->element.key.radius > key.radius) && (root->left != NULL))
return CHfind(root->left,key);
else {
if ((root->element.key.angle > key.angle) && (root->right != NULL))
return CHfind(root->right,key);
else if ((root->element.key.angle > key.angle) && (root->left != NULL))
return CHfind(root->left,key);
else {
if ((root->element.key.number < key.number) && (root->right != NULL))
return CHfind(root->right,key);
else if ((root->element.key.number > key.number) && (root->left != NULL))
return CHfind(root->left,key);
else
return root; }
}
}
*/
CHsplay_node *CHrotate(CHsplay_node *sn)
{
CHsplay_node *temp;
if(sn->father->left==sn)
{ /*left*/
sn->father->left = sn->right;
if (sn->right != NULL)
sn->right->father = sn->father;
sn->right = sn->father;
}
else
{ /*right*/
sn->father->right = sn->left;
if (sn->left != NULL)
sn->left->father = sn->father;
sn->left = sn->father;
}
temp = sn->father->father;
sn->father->father = sn;
if (temp != NULL)
if (temp -> left == sn->father)
temp->left = sn;
else
temp->right = sn;
sn->father=temp;
return sn;
}
void *CHsplay(CHsplay_node **root, key key)
{
CHsplay_node *temp;
temp=CHfind(*root,key);
while (temp->father != NULL) {
if (temp->father->father==NULL) { /* CHrotate x */
temp=CHrotate(temp); }
else if ((temp->father->left == temp) &&
(temp->father->father->left == temp->father))
{ /* x and y both left children, CHrotate y, CHrotate x */
CHrotate(temp->father);
temp=CHrotate(temp); }
else if ((temp->father->right == temp) &&
(temp->father->father->right == temp->father))
{ /* x and y both right children, CHrotate y, CHrotate x */
CHrotate(temp->father);
temp=CHrotate(temp); }
else { /* CHrotate x, CHrotate x */
temp=CHrotate(temp);
temp=CHrotate(temp); }
}
(*root)=temp;
}
void CHtraverse(CHsplay_node *root)
{
if (root != NULL) {
CHtraverse(root->left);
printf("(%d,%d) key: (%f,%f,%d)\n",((root->element.point)->node.x),
((root->element.point)->node.y),(root->element.key.radius),
(root->element.key.angle),(root->element.key.number));
CHtraverse(root->right); }
}
void CHfree_tree(CHsplay_node *root)
{
if (root != NULL) {
CHfree_tree(root->left);
CHfree_tree(root->right);
free(root); }
}
CHsplay_node *CHcreate_node(CHpoints *p)
{
CHsplay_node *new_node;
dpoint c;
key key;
if (!(new_node = (CHsplay_node *)malloc(sizeof(CHsplay_node)))) {
printf("Can't create node\n");
exit(0); }
new_node->left = NULL;
new_node->right = NULL;
new_node->father = NULL;
c=centre(before(p)->node,p->node,next(p)->node);
key.radius=radius2(p->node,c);
key.angle=angle(before(p),p,next(p));
key.number=p->number;
new_node->element.key = key;
new_node->element.point = p;
return new_node;
}
/* Operations */
CHsplay_node *CHinit(void)
{
return NULL;
}
void *CHinsert(CHsplay_node **root, CHpoints *p) {
CHsplay_node *temp;
temp = CHcreate_node(p);
if (*root != NULL) {
CHsplay(root,temp->element.key);
if (((*root)->element.key.radius > temp->element.key.radius) ||
(((*root)->element.key.radius == temp->element.key.radius) &&
((*root)->element.key.angle < temp->element.key.angle)) ||
((((*root)->element.key.radius == temp->element.key.radius) &&
((*root)->element.key.angle == temp->element.key.angle)) &&
(((*root)->element.key.number > temp->element.key.number)))) {
temp->left = (*root)->left;
if (temp->left != NULL)
temp->left->father = temp;
temp->right = (*root);
(*root)->left = NULL; }
else {
temp->right = (*root)->right;
if (temp->right != NULL)
temp->right->father = temp;
temp->left = (*root);
(*root)->right = NULL; }
(*root)->father = temp; }
*root = temp;
}
CHpoints *CHdelete_max(CHsplay_node **root) {
CHsplay_element max_elm;
CHsplay_node *max_node;
key key;
key.radius=((double)3.40282346638528860e+38);
key.angle=1000;
key.number=1000;
if (*root != NULL) {
CHsplay(root,key);
max_elm=(*root)->element;
max_node=*root;
*root = (*root)->left;
if (*root)
(*root)->father = NULL;
free(max_node); }
else {
printf("No elements in tree! [CHdelete_max]\n");
return 0; }
return max_elm.point;
}
void CHdelete(CHsplay_node **root, key key) {
CHsplay_node *node,*tmp1,*tmp2;
struct key tmp_key;
if (*root != NULL) {
CHsplay(root,key); /* Splay around the key we want to delete */
node=*root; /* Temporary pointer to be freed */
tmp1=(*root)->left; /* Left sub tree */
tmp2=(*root)->right; /* Right sub tree */
if ((tmp1 == NULL) && (tmp2 == NULL)) /* No elements left */
(*root)=NULL;
else if ((tmp1 == NULL) && (tmp2 != NULL)) { /* right sub tree empty */
(*root)=tmp2;
(*root)->father=NULL; }
else if ((tmp1 != NULL) && (tmp2 == NULL)) { /* left sub tree empty */
(*root)=tmp1;
(*root)->father=NULL; }
else { /* both sub trees are non-empty */
tmp_key.radius=((double)3.40282346638528860e+38);
tmp_key.angle=1000;
tmp_key.number=1000;
tmp1->father=NULL;
CHsplay(&tmp1,tmp_key); /* make tree without right sub tree */
tmp_key.radius=-1;
tmp_key.angle=-1;
tmp_key.number=-1;
tmp2->father=NULL; /* make tree without left sub tree */
CHsplay(&tmp2,tmp_key);
tmp1->right=tmp2;
tmp1->right->father=tmp1;
(*root)=tmp1; }
free(node);
}
else
printf("No elements in tree! [CHdelete]\n");
}