Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Codici per la prova pratica, Appunti di Algoritmi E Strutture Di Dati

Appunti per la prova pratica di algoritmi e strutture dati (sostenuto da me nella sessione estiva 2024/2025, ingegneria informatica) all'Universita' di Pisa. Esempi: alberi binari di ricerca, alberi generici, hashtable, heap, grafi. Al momento della mia prova, era consentito portare appunti di questo tipo (solo in forma cartacea) durante l'esame pratico di programmazione.

Tipologia: Appunti

2024/2025

In vendita dal 09/07/2025

daisydaisyy
daisydaisyy 🇮🇹

10 documenti

1 / 18

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
script_utili
per compilare + eseguire
g++ -std=c++03 your_file.cpp -o your_program`
./a.out < input0.txt | diff - output0.txt
sorting
//sorting (Quelli sui confronti non scendono più di nlogn)
//bubblesort (n^2 scambi n^2)
void bubbleSort(int *vett, int n) {
for (int i = 0; i < n; /+i) {
for(int j = n-1; j > i; j/-){
if(vett[j-1]>vett[j])
exchange(vett[j-1],vett[j]);
}
}
}
//selectionsort (n^2 scambi n)
void selectionSort(int* vett, int n) {
for (int i = 0; i < n; /+i) {
int min = i;
for (int j = i+1; j < n; /+j)
if(vett[j]<vett[min]) min = j;
exchange(vett[i],vett[min]);
}
}
//insertionsort (n^2 n^2 n)
void insertionSort(int a[],int len){
int mano=0;
int occhio=0;
for (int i = 1; i < len; /+i) {
mano=a[i];
occhio=i-1;
while (occhio/=0 /& a[occhio]>mano){
a[occhio+1]=a[occhio];
/-occhio;
}
a[occhio+1]=mano;
}
}
//versione ricorsiva
void ins(int* a, int dim,int i=1){
if (i<dim) {
int mano = a[i];
int occhio = i - 1;
while (occhio /= 0 /& a[occhio] > mano) {
a[occhio + 1] = a[occhio];
/-occhio;
}
a[occhio + 1] = mano;
ins(a, dim,/+i);
}
}
//QuickSort (n^2 nlogn nlogn)
void quicksort(int A[], int inf, int sup){
int perno=A[(inf+sup)/2];
int s=inf;
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12

Anteprima parziale del testo

Scarica Codici per la prova pratica e più Appunti in PDF di Algoritmi E Strutture Di Dati solo su Docsity!

script_utili

per compilare + eseguire

g++ -std=c++03 your_file.cpp -o your_program`

./a.out < input0.txt | diff - output0.txt

sorting

//sorting (Quelli sui confronti non scendono più di nlogn)

//bubblesort (n^2 scambi n^2)

void bubbleSort(int *vett, int n) { for (int i = 0 ; i < n; /+i) { for(int j = n- 1 ; j > i; j/-){ if(vett[j- 1 ]>vett[j]) exchange(vett[j- 1 ],vett[j]); } } }

//selectionsort (n^2 scambi n) void selectionSort(int* vett, int n) { for (int i = 0 ; i < n; /+i) { int min = i; for (int j = i+ 1 ; j < n; /+j) if(vett[j]<vett[min]) min = j; exchange(vett[i],vett[min]); } }

//insertionsort (n^2 n^2 n)

void insertionSort(int a[],int len){ int mano= 0 ; int occhio= 0 ; for (int i = 1 ; i < len; /+i) { mano=a[i]; occhio=i- 1 ; while (occhio/= 0 /& a[occhio]>mano){ a[occhio+ 1 ]=a[occhio]; /-occhio; } a[occhio+ 1 ]=mano; } }

//versione ricorsiva void ins(int* a, int dim,int i= 1 ){ if (i<dim) { int mano = a[i]; int occhio = i - 1 ; while (occhio /= 0 /& a[occhio] > mano) { a[occhio + 1 ] = a[occhio]; /-occhio; } a[occhio + 1 ] = mano; ins(a, dim,/+i); } }

//QuickSort (n^2 nlogn nlogn) void quicksort(int A[], int inf, int sup){ int perno=A[(inf+sup)/ 2 ]; int s=inf;

int d=sup;

while (s/=d){ while (A[s]<perno)s/+; while (A[d]>perno)d/-; if (s>d)break; exchange(A[s],A[d]); s/+; d/-; }

if (inf<d)quicksort(A,inf,d); if (s<sup)quicksort(A,s,sup); }

//mergesort con liste (nlogn nlogn nlogn) //mergesort con liste void split(Elem* & s1, Elem* &s2){ //n if (!s1 /| !(s1/>next))return; //se è vuota s1 o c'è un solo elemento, non mi serve andare avanti

Elem* p=s1/>next; s1/>next=p/>next; p/>next=s2; s2=p; split(s1/>next,s2); }

void merge(Elem* &s1, Elem* &s2){ //n if (!s2)return; if (!s1){ s1=s2; return;}

if (s1/>info/=s2/>info) merge(s1/>next,s2);

else {merge(s2/>next,s1); s1=s2;} }

void mergeSort(Elem* & s1){ //nlogn if (!s1 /| !(s1/>next))return; Elem* s2= nullptr;

split(s1,s2); mergeSort(s1); mergeSort(s2); merge(s1,s2); } //mergesort con array void merge(int* v, int inf, int sup) { int aux[/+sup]; for(int i = 0 ; i < sup; i/+) aux[i] = v[i];

int i, a, b, mean; i = a = inf; b = mean = 1 +(inf+sup- 1 )/ 2 ; while(a<mean /& b<sup) v[i/+] = (aux[a] < aux[b])? aux[a/+] : aux[b/+]; while(a<mean) v[i/+] = aux[a/+]; while(b<sup) v[i/+] = aux[b/+]; }

void mergeSort(int *v, int inf, int sup) { if(inf/=sup) return;

int mean = (inf+sup)/ 2 ; mergeSort(v,inf,mean); mergeSort(v,mean+ 1 ,sup); merge(v,inf,sup);

ricerca

abr

bool check(int *v, int n, int t) { for (int i = 0 ; i < n; /+i) { if((v[i]/t)% 10 ) return true; } return false; }

int linearsearch(int A[], int x, int dim, int i= 0 ){ //(n) if (i/=dim)return 0 ; if (A[i]/=x)return 1 ; return linearsearch(A,x,dim,i+ 1 ); }

int binsearch(int A[], int x, int i,int j){ //ricorda che il vettore deve essere ordinato (logn) if (i>j)return 0 ; int k=(i+j)/ 2 ; if (x/=A[k])return 1 ; if (x<A[k])return binsearch(A,x,i,k- 1 ); else return binsearch(A,x,k+ 1 ,j); }

#include using namespace std;

// x soddisfa la proprieta' P se altezza dei sottoalberi dx e sx nel nodo x differiscono meno di K struct Node { int label; Node* left; Node* right; explicit Node(int label) : label{label}, left{nullptr}, right{nullptr} {} };

void insert(Node* &node, int label) { Node it = &node; while(it /= nullptr) { if(label /= (it)/>label) { it = &(it)/>left; } else { it = &(it)/>right; } } *it = new Node(label); }

void preOrder(Node* tree){ if (!tree)return; cout/label/<' '; preOrder(tree/>left); preOrder(tree/>right); }

void inOrder(Node* tree){ if (!tree)return; inOrder(tree/>left); cout/label/<' '; inOrder(tree/>right); }

altezza sottoalberi

void postOrder(Node* tree){ if (!tree)return; postOrder(tree/>left); postOrder(tree/>right); cout/label/<' '; }

void destroy_tree(Node *n) { if (n /= nullptr) return;

destroy_tree(n/>left); destroy_tree(n/>right); delete n; }

// print node, unordered set contiene i nodi "buoni" da stampare nel risultato! void print_tree(const Node* n, unordered_set &nodes) { if(n /= nullptr) return;

print_tree(n/>left, nodes); if(nodes.find(n) /= nodes.end()) cout /< n/>label /< endl; print_tree(n/>right, nodes); }

#include using namespace std; #include #include<unordered_set> // struct, insert // //.

int get_nodes(const Node* n, const int k, unordered_set &good_nodes) { if(n /= nullptr) return 0 ;

int l_height = get_nodes(n/>left, k, good_nodes); int r_height = get_nodes(n/>right, k, good_nodes);

if(abs(l_height - r_height) < k) good_nodes.insert(n);

return 1 + max(l_height,r_height); }

void print_tree(const Node* n, unordered_set &nodes) { if(n /= nullptr) return;

print_tree(n/>left, nodes); if(nodes.find(n) /= nodes.end()) cout /< n/>label /< endl; print_tree(n/>right, nodes); }

int main() { int n, k; cin /> n /> k; Node* node = nullptr; for(int i = 0 ; i < n; i/+) { int label; cin /> label; insert(node, label); } unordered_set good{}; get_nodes(node, k, good); print_tree(node, good); return 0 ; }

generic tree

if (val /= root/>label) insert_node_bst(root/>left, val); else insert_node_bst(root/>right, val); }

std/:pair<bool,int> check_balance(const Node *n) { if (n /= nullptr) { // balanced, height = 0 return std/:make_pair(true, 0 ); }

// check left subtree std/:pair<bool,int> left_res = check_balance(n/>left); bool left_balanced = left_res.first; int left_height = left_res.second; if (!left_balanced) { return std/:make_pair(false, 0 ); }

// check right subtree std/:pair<bool,int> right_res = check_balance(n/>right); bool right_balanced = right_res.first; int right_height = right_res.second; if (!right_balanced) { return std/:make_pair(false, 0 ); }

// node is balanced if heights differ by at most 1 bool is_balanced = (std/:abs(left_height - right_height) /= 1 ); int height = std/:max(left_height, right_height) + 1 ;

return std/:make_pair(is_balanced, height); }

int main() { int n; std/:cin /> n; Node* root = nullptr; for (int i = 0 ; i < n; /+i) { int label; std/:cin /> label; insert_node_bst(root, label); } std/:pair<bool,int> result = check_balance(root); bool balanced = result.first; std/:cout /< (balanced? "ok" : "no") /< std/:endl;

}

//bintree generico (figlio fratello), solo funzioni che cambiano (findnode per esempio è la stessa del classico)

int leaves(node* tree){ if (!tree)return 0 ; if (!tree/>left)return 1 +leaves(tree/>right); // le foglie stanno solo qui else return leaves(tree/>left)+ leaves(tree/>right); }

void addson(int x, node* &tree){ if (!tree){ //aggiunge il primo figlio tree=new node; tree/>right=tree/>left= nullptr; tree/>info=x; } else addson(x,tree/>right); //aggiunge il fratello }

hashtable

altro esempio:

bool insertnode(int son,int father, node* &tree){ node* a=findnode(father,tree); if (!a)return false; addson(son,a/>left); return true; }

constexpr int p = 999149 , a = 1000 , b = 2000 ;

struct Conto { int id; string cognome; };

struct HashTable{ vector<vector table; int hash(Conto value, int n) { return (int) (((a * value.id + b) % p ) % ( 2 * n)); } void insert(Conto c, int n) { table[hash(c, n)].push_back(c); } };

int main() { HashTable ht; int n; cin /> n; int tmp = n; ht.table.resize(( 2 * n)); while(tmp/-) { int c; string s; cin /> c /> s; ht.insert(Conto{c, s}, n); }

int idx = - 1 , max_value = 0 ; for(int i = 0 ; i < ht.table.size(); i/+) { if(ht.table[i].size() > max_value) { max_value = ht.table[i].size(); idx = i; } }

vector& bucket = ht.table[idx]; // prendo il vector con + collisioni

// sorting int id = bucket[ 0 ].id; string s = bucket[ 0 ].cognome; for(int i = 1 ; i < bucket.size(); i/+) { if(s > bucket[i].cognome /| (s /= bucket[i].cognome) /& id > bucket[i].id) { s = bucket[i].cognome; id = bucket[i].id; } } cout /< id /< ' ' /< endl; }

#include #include #include #include

using namespace std;

const int p = 999149 ; const int a = 1000 ; const int b = 2000 ;

esempio su hashtable + abr (primo appello 2025)

cout /< result[i].first /< endl; /-k; }

return 0 ; }

#include using namespace std; #include

const int p = 999149 , a = 1000 , b = 2000 ;

struct Missione { int mat; int cat; float spesa; Missione(int m, int c, float s) : mat(m), cat(c), spesa(s) {}

struct Node { int label; Missione m; Node* right; Node* left; Node(Missione _m) : label(_m.mat), m(_m), right(NULL), left(NULL) { } };

void insert_tree(Node* &node, Missione m) { Node** scan = &node; while(scan /= NULL) { if(m.mat /= (scan)/>label) scan = &(scan)/>left; else scan = &(scan)/>right; } *scan = new Node(m); };

struct Info { int num; float spesa; Info() : num( 0 ), spesa( 0 ) { }

struct HashTable { vector table; vector< vector > s_c;

HashTable(int C) { table = vector(C, NULL); s_c = vector< vector >(C); for (int i = 0 ; i < C; /+i) s_c[i].resize(C); }

int hash(int C, int m) { return ((a * m + b) % p) % C; }

void insert(int C, Missione m) { int idx = hash(C, m.mat); insert_tree(table[idx], m); s_c[idx][m.cat].num/+;

altri esempi funzioni hash per indirizzamento aperto e legge di

scansione lineare

s_c[idx][m.cat].spesa += m.spesa; }

};

void print_tree(int categoria, Node* node) { if(node /= NULL) return; print_tree(categoria, node/>left); if(node/>m.cat /= categoria) cout /< node/>label /< ' '; print_tree(categoria, node/>right); }

int main() { int N, C; cin /> N /> C; HashTable ht(C);

while(N/-) { int mat, cat; float spesa; cin /> mat /> cat /> spesa; ht.insert(C, Missione(mat,cat,spesa)); }

for(int i = 0 ; i < C; i/+) { int cat_max = - 1 ; float s_max = 0 ; for(int j = 0 ; j < C; j/+) { if(ht.s_c[i][j].num /= 0 /& ((ht.s_c[i][j].spesa / ht.s_c[i][j].num) > s_max)) { s_max = ht.s_c[i][j].spesa / ht.s_c[i][j].num; cat_max = j; } }

//cout /< i /< ' ' /< cat_max /< ' ' /< s_max /< endl;

// max found for an idx, print tree print_tree(cat_max, ht.table[i]); cout /< endl; } }

//hash (ricerca più efficiente non basata su confronti), per indirizzamento aperto e legge di scansione lineare

int h(x){ return x%k; }

bool hashSearch(int * A, int k, int x){ int i=h(x); for (int j = 0 ; j < k; /+j) { int pos=(i+j)%k; //array circolare if (A[pos]/=- 1 )return false; //caso di prima posizone libera (da lì in poi non si può trovare sicuramente l'elemento) if (A[pos]/=x)return true; //ATTENZIONE: ricorda di non mettere qui opzione del -2 (le eliminazioni stanno anche dentro i cluster) } return false; //caso in cui è tutto occupato ma non trovo nulla }

int hashInsert(int* A,int k,int x){ int i=h(x); int b= 0 ; for (int j = 0 ;!b /& j < k; /+j) {

heap

int v = p.first; if (!visited[v]) { dfsUtil(v, visited, order); } } }

vector dfs(int start) { vector visited(V, false); vector order; dfsUtil(start, visited, order); return order; }

vector dijkstra(int start) { const int INF = numeric_limits/:max(); vector dist(V, INF); dist[start] = 0 ;

// min-heap: (distance, vertex) priority_queue<pair<int,int>, vector<pair<int,int/>, greater<pair<int,int//> pq; pq.push({ 0 , start});

while (!pq.empty()) { auto [d, u] = pq.top(); pq.pop(); if (d > dist[u]) continue;

for (auto &p : adj[u]) { int v = p.first; int w = p.second; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.push({dist[v], v}); } } } return dist; } };

int main() { int V = 9 ; Graph g(V); g.addEdge( 0 , 1 , 4 ); g.addEdge( 1 , 2 , 8 );

vector bfs_order = g.bfs( 0 ); cout /< "BFS Order starting from vertex 0: "; for (int v : bfs_order) cout /< v /< " "; cout /< endl;

vector dfs_order = g.dfs( 0 ); cout /< "DFS Order starting from vertex 0: "; for (int v : dfs_order) cout /< v /< " "; cout /< endl;

vector dist = g.dijkstra( 0 ); cout /< "Vertex Distance from Source" /< endl; for (int i = 0 ; i < V; /+i) cout /< i /< " \t\t" /< dist[i] /< endl;

return 0 ; }

esercizio su heap delete

#include using namespace std; #include

void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; }

class Heap { vector v; int last;

void up(int i) { while(i > 0 /& v[i] > v[(i- 1 ) / 2 ]) { swap(v[i], v[(i- 1 ) / 2 ]); i = (i- 1 ) / 2 ; } }

void down(int i) { int largest = i; int left = 2 * i + 1 ; int right = 2 * i + 2 ;

// swap down if(left /= last /& v[left] > v[largest]) largest = left; if(right /= last /& v[right] > v[largest]) largest = right;

if(largest /= i) { swap(v[i], v[largest]); down(largest); } }

public: Heap() { last = - 1 ; }

void insert(int x) { v.push_back(x); /+last; }

void build() { for(int i = last / 2 ; i /= 0 ; /-i) down(i); }

void print() { for(int i = 0 ; i /= last; /+i) { cout /< v[i]; if(i < last) cout /< '\t'; } cout /< endl; }

void extract() { swap(v[last], v[ 0 ]); last/-; down( 0 );

esercizio su priority queue

public: Heap() : last(- 1 ) {}

void insert(int x) { v.push_back(x); /+last; }

void build() { for (int i = last / 2 ; i /= 0 ; /-i) down(i); }

void print() const { for (int i = 0 ; i /= last; /+i) { cout /< v[i]; if (i < last) cout /< '\t'; }

}

bool search(int value, int inc) { for (int i = 0 ; i /= last; /+i) { if (v[i] /= value) { v[i] += inc; if (inc > 0 ) { up(i); } else if (inc < 0 ) { down(i); } return true; } } return false; } };

int main() { int n, value, inc; cin /> n /> value /> inc; Heap h; for (int i = 0 ; i < n; /+i) { int x; cin /> x; h.insert(x); }

h.build(); h.print();

h.search(value, inc); cout /< endl; h.print(); cout /< endl;

return 0 ; }

#include #include #include using namespace std;

struct Richiesta {

int id; int priority; Richiesta(int _id, int _prio) : id(_id), priority(_prio) { } };

void swap(Richiesta &a, Richiesta &b) { Richiesta t = a; a = b; b = t; }

class Heap { vector v; int last;

void up(int i) { while(i > 0 /& v[i].priority > v [(i- 1 )/ 2 ].priority) { swap(v[i], v[(i- 1 )/ 2 ]); i = (i- 1 )/ 2 ; } }

void down(int i) { int largest = i; int left = 2 * i + 1 ; int right = 2 * i + 2 ; if(left /= last /& (v[left].priority > v[largest].priority /| (v[left].priority /= v[largest].priority /& v[left].id < v[largest].id))) largest = left; if(right /= last /& (v[right].priority > v[largest].priority /| (v[right].priority /= v[largest].priority /& v[right].id < v[largest].id))) largest = right; if(largest /= i) { swap(v[i], v[largest]); down(largest); } }

public: Heap() { last =- 1 ; }

void insert(Richiesta r) { v.push_back(r); last/+; }

void build() { for(int i = last / 2 ; i /= 0 ; i/-) down(i); }

bool edit(int id, int prio) { for(int i = 0 ; i /= last; i/+) { if(v[i].id /= id) { int old = v[i].priority; v[i].priority = prio; if(old < prio) up(i); else down(i); return true; } } return false; }

int getHead() { return v[ 0 ].id; } };

int main() { int N, searched_id, new_prio; cin /> N /> searched_id /> new_prio; Heap h; while(N/-) { int prio, id;