feat: Initial commit
This commit is contained in:
266
Laboratorio 8/Esercizio 3/ExrateBST.c
Normal file
266
Laboratorio 8/Esercizio 3/ExrateBST.c
Normal file
@@ -0,0 +1,266 @@
|
||||
// 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);
|
||||
}
|
||||
Reference in New Issue
Block a user