1
0
Files
Laboratori-ASD/Laboratorio 8/Esercizio 3/ExrateBST.c
2024-03-22 17:37:24 +01:00

267 lines
5.6 KiB
C

// Laboratorio 8 - Esercizio 3 - ExrateBST.c
// Matteo Schiff - s295565
#include <stdlib.h>
#include "ExrateBST.h"
typedef struct node *link;
struct node
{
Exrate exrate;
int N;
link left, right;
};
struct exrateBST
{
link root;
link z;
int N;
};
static link createNode(Exrate exrate, link l, link r, int N)
{
link new = malloc(sizeof(*new));
new->exrate = exrate;
new->left = l;
new->right = r;
new->N = N;
return new;
}
static link rotR(link n)
{
link t = n->left;
n->left = t->right;
t->right = n;
t->N = n->N;
n->N = 1;
n->N += (n->left) ? n->left->N : 0;
n->N += (n->right) ? n->right->N : 0;
return t;
}
static link rotL(link h)
{
link t = h->right;
h->right = t->left;
t->left = h;
t->N = h->N;
h->N = 1;
h->N += (h->left) ? h->left->N : 0;
h->N += (h->right) ? h->right->N : 0;
return t;
}
ExrateBST ExrateBSTCreate()
{
ExrateBST new = malloc(sizeof(*new));
new->z = createNode(ExrateEmpty(), NULL, NULL, 0);
new->root = new->z;
return new;
}
static void freeBST(link n, link z)
{
if (n == z)
return;
free(n->left);
free(n->right);
free(n);
}
void ExrateBSTFree(ExrateBST ebst)
{
freeBST(ebst->root, ebst->z);
free(ebst->z);
free(ebst);
}
static link search(link n, DateTime dt, link z)
{
if (n == z)
return z;
int c = DateTimeCompare(dt, n->exrate.datetime);
if (c == 0)
return n;
if (c > 0)
return search(n->right, dt, z);
else
return search(n->left, dt, z);
}
Exrate ExrateBSTSearch(ExrateBST ebst, DateTime dt)
{
// nota: se search restituisce z, allora z,exrate è l'exrate nullo
return search(ebst->root, dt, ebst->z)->exrate;
}
static void ExrateBSTInsertLeaf(ExrateBST ebst, Exrate exrate)
{
if (ebst->root == ebst->z)
{
ebst->root = createNode(exrate, ebst->z, ebst->z, 1);
ebst->N++;
return;
}
link *n = &ebst->root;
while (*n != ebst->z)
{
(*n)->N++;
if (DateTimeCompare(exrate.datetime, (*n)->exrate.datetime) > 0)
{
n = &(*n)->right;
}
else
{
n = &(*n)->left;
}
}
*n = createNode(exrate, ebst->z, ebst->z, 1);
ebst->N++;
}
void ExrateBSTInsert(ExrateBST ebst, Exrate exrate)
{
link node = search(ebst->root, exrate.datetime, ebst->z);
if (node != ebst->z)
{
// Merge exrate
node->exrate.q = ((node->exrate.n * node->exrate.q) + (exrate.n * exrate.q)) / (node->exrate.n + exrate.n);
node->exrate.n += exrate.n;
}
else
{
ExrateBSTInsertLeaf(ebst, exrate);
}
}
static void mergeR(ExrateBST dst, link r, link z)
{
if (r == z)
return;
mergeR(dst, r->left, z);
mergeR(dst, r->right, z);
ExrateBSTInsert(dst, r->exrate);
}
void ExrateBSTMerge(ExrateBST dst, ExrateBST src)
{
mergeR(dst, src->root, src->z);
}
static void getMaxMinLengthR(link n, link z, int *min, int *max, int *counter)
{
if (n == z)
{
if (*counter < *min)
*min = *counter;
if (*counter > *max)
*max = *counter;
return;
}
(*counter)++;
getMaxMinLengthR(n->left, z, min, max, counter);
getMaxMinLengthR(n->right, z, min, max, counter);
(*counter)--;
}
static int getMaxMinDiff(ExrateBST ebst)
{
int counter = 0, min = ebst->N, max = 0;
getMaxMinLengthR(ebst->root, ebst->z, &min, &max, &counter);
return max - min;
}
link partR(link h, int r)
{
int t = h->left->N;
if (t > r)
{
h->left = partR(h->left, r);
h = rotR(h);
}
if (t < r)
{
h->right = partR(h->right, r - t - 1);
h = rotL(h);
}
return h;
}
static link balanceR(link h, link z)
{
int r;
if (h == z)
return z;
r = (h->N + 1) / 2 - 1;
h = partR(h, r);
h->left = balanceR(h->left, z);
h->right = balanceR(h->right, z);
return h;
}
void visitInOrderCheckInterval(link h, link z, DateTime dt1, DateTime dt2, int interval, Exrate *min, Exrate *max) {
if (h == z)
return;
visitInOrderCheckInterval(h->left,z,dt1,dt2,interval,min,max);
if (!interval || (DateTimeCompare(h->exrate.datetime, dt1) >= 0 && DateTimeCompare(h->exrate.datetime, dt2) <= 0)) {
if (h->exrate.q > max->q)
*max = h->exrate;
if (h->exrate.q < max->q)
*min = h->exrate;
}
visitInOrderCheckInterval(h->right,z,dt1,dt2,interval,min,max);
}
void ExrateBSTBalance(ExrateBST bst)
{
// calcola la differenza (distanza root -> nodo massima) - (distanza root -> nodo minima)
int diff = getMaxMinDiff(bst);
if (diff >= S)
{
printf("La differenza tra il cammino più corto e quello più lungo è di %d, bilancio l'albero...\n", diff);
bst->root = balanceR(bst->root, bst->z);
diff = getMaxMinDiff(bst);
printf("Bilanciato, ora la differenza è di: %d\n", diff);
}
else
{
printf("La differenza tra il cammino più corto e quello più lungo è di %d, non è necessario bilanciare l'albero\n", diff);
}
}
void ExrateBSTMinMaxW(ExrateBST bst, DateTime dt1, DateTime dt2, int interval) {
Exrate min, max;
min = max = bst->root->exrate;
visitInOrderCheckInterval(bst->root, bst->z, dt1, dt2, interval, &min, &max);
printf("Quotazione minima: ");
ExratePrint(min);
printf("Quotazione massima: ");
ExratePrint(max);
}
void ExrateBSTMinMax(ExrateBST bst) {
DateTime empty;
ExrateBSTMinMaxW(bst, empty, empty, 0);
}
void ExrateBSTMinMaxInInterval(ExrateBST bst, DateTime dt1, DateTime dt2) {
ExrateBSTMinMaxW(bst, dt1, dt2, 1);
}