/* Nome: Mario Cognome: Montanari Classe: 3AIN Data: 05/05/2025 Funzione di Shaker Sort che ordina direttamente su un file */ #include using namespace std; typedef struct { int value; } basetype; void fshakerSort(FILE * file); void swapInFile(FILE * file, int i, int j); void fprint(const char * filename); int main(void) { const char * filename = "data.bin"; // Apertura del file FILE * file = fopen(filename, "r+b"); if (file != NULL) { fshakerSort(file); // Esegui lo shaker sort fprint(filename); // Stampa il risultato fclose(file); // Chiudi il file } else { perror("Errore nell'aprire il file"); } return 0; } void fshakerSort(FILE * file) { // Spostati alla fine del file per ottenere il numero di elementi fseek(file, 0, SEEK_END); long n = ftell(file) / sizeof(basetype); if (n < 2) { return; // Se il file ha meno di due elementi, non รจ necessario ordinare } rewind(file); // Torna all'inizio del file int left = 0; int right = n - 1; bool swapped = true; while (left < right && swapped) { swapped = false; // Passaggio da sinistra verso destra for (int i = left; i < right; i++) { basetype a, b; // Leggi i due valori da scambiare fseek(file, i * sizeof(basetype), SEEK_SET); fread(&a, sizeof(basetype), 1, file); fseek(file, (i + 1) * sizeof(basetype), SEEK_SET); fread(&b, sizeof(basetype), 1, file); if (a.value > b.value) { swapInFile(file, i, i + 1); // Effettua lo swap se i valori sono nell'ordine sbagliato swapped = true; } } right--; // Riduci l'area da esaminare // Passaggio da destra verso sinistra for (int i = right; i > left; i--) { basetype a, b; fseek(file, (i - 1) * sizeof(basetype), SEEK_SET); fread(&a, sizeof(basetype), 1, file); fseek(file, i * sizeof(basetype), SEEK_SET); fread(&b, sizeof(basetype), 1, file); if (a.value > b.value) { swapInFile(file, i - 1, i); // Effettua lo swap se i valori sono nell'ordine sbagliato swapped = true; } } left++; // Espandi l'area da esaminare } } void swapInFile(FILE * file, int i, int j) { if (i == j) { return; // Nessun bisogno di fare uno swap se gli indici sono uguali } basetype a, b; // Leggi i valori da scambiare fseek(file, i * sizeof(basetype), SEEK_SET); if (fread(&a, sizeof(basetype), 1, file) != 1) { cout << "Errore di lettura (i)!" << endl; return; } fseek(file, j * sizeof(basetype), SEEK_SET); if (fread(&b, sizeof(basetype), 1, file) != 1) { cout << "Errore di lettura (j)!" << endl; return; } // Scrivi i valori scambiati fseek(file, i * sizeof(basetype), SEEK_SET); if (fwrite(&b, sizeof(basetype), 1, file) != 1) { cout << "Errore di scrittura (i)!" << endl; return; } fseek(file, j * sizeof(basetype), SEEK_SET); if (fwrite(&a, sizeof(basetype), 1, file) != 1) { cout << "Errore di scrittura (j)!" << endl; return; } } void fprint(const char * filename) { FILE * file = fopen(filename, "rb"); if (file != NULL) { basetype temp; while (fread(&temp, sizeof(basetype), 1, file) == 1) { cout << temp.value << " "; // Stampa i valori letti } cout << endl; fclose(file); } else { perror("Errore nell'aprire il file per la lettura"); } }