147 lines
3.4 KiB
C++
147 lines
3.4 KiB
C++
/*
|
|
Nome: Mario
|
|
Cognome: Montanari
|
|
Classe: 3AIN
|
|
Data: 05/05/2025
|
|
|
|
Funzione di Shaker Sort che ordina direttamente su un file
|
|
*/
|
|
|
|
#include <iostream>
|
|
|
|
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");
|
|
}
|
|
} |