Data Structures 101: Arrays – A Visual Introduction for Beginners

Conosci le strutture dati che usi ogni giorno.

👋 Benvenuto! Iniziamo con un po’ di contesto vitale. Lascia che ti chieda questo:
✅ Ascolti musica sul tuo smartphone?
✅ Tieni una lista di contatti sul tuo telefono?
✅ Hai mai visto una classifica durante una competizione?

Se la tua risposta è “sì” a una di queste domande, allora è quasi certo che hai usato gli array e non lo sapevi nemmeno! Gli array sono strutture di dati molto potenti che memorizzano liste di elementi. Hanno infinite applicazioni. Sono molto importanti nel mondo dell’informatica.

In questo articolo, imparerai i pro e i contro degli array, la loro struttura, le operazioni e i casi d’uso.

Cominciamo! 👍

🔎 Deep Dive Into the Basic Structure of Arrays

Per capire come funzionano, è molto utile visualizzare la memoria del tuo computer come una griglia, proprio come quella sotto. Ogni informazione è memorizzata in uno di quei piccoli elementi (quadrati) che formano la griglia.

Gli array sfruttano questa struttura a “griglia” per memorizzare liste di informazioni correlate in posizioni di memoria adiacenti per garantire un’estrema efficienza nel trovare quei valori. 🔳🔳🔳🔳 🔳

Puoi pensare agli array in questo modo:

I loro elementi sono uno accanto all’altro nella memoria. Se avete bisogno di accedere a più di uno di essi, il processo è estremamente ottimizzato perché il computer sa già dove si trova il valore.

Fantastico, vero? Impariamo come funziona dietro le quinte! 😃

📚 Classificazione

Gli array sono classificati come strutture di dati omogenee perché memorizzano elementi dello stesso tipo.

Possono memorizzare numeri, stringhe, valori booleani (vero e falso), caratteri, oggetti e così via. Ma una volta definito il tipo di valori che il vostro array memorizzerà, tutti i suoi elementi devono essere dello stesso tipo. Non puoi “mischiare” diversi tipi di dati.

👀 Lettura dei valori – La magia inizia!

L’incredibile potenza degli array deriva dalla loro efficienza nell’accesso ai valori. Questo si ottiene grazie alla sua struttura a griglia. Diamo un’occhiata più in dettaglio.🔍

Quando crei un array, tu:
– lo assegni ad una variabile. 👈
– Definisci il tipo di elementi che memorizzerà. 🎈
– Definisci la sua dimensione (il numero massimo di elementi). 📚

💡 Nota: Il nome che assegni a questa variabile è molto importante perché lo userai più tardi nel tuo codice per accedere ai valori e per modificare l’array.

Ma come puoi dire al computer a quale particolare valore vuoi accedere? Questo è dove gli indici prendono un ruolo vitale!

1️⃣ Indici

Utilizzi quello che si chiama un “indice” (“indici” al plurale) per accedere a un valore in un array. Questo è un numero che si riferisce alla posizione in cui il valore è memorizzato.

Come puoi vedere nel diagramma qui sotto, il primo elemento della matrice è riferito all’indice 0. Man mano che ci si sposta più a destra, l’indice aumenta di uno per ogni spazio in memoria.

💡 Nota: so che all’inizio sembra strano iniziare a contare da 0 invece che da 1, ma questo è chiamato Zero-Based Numbering. È molto comune in informatica.

La sintassi generale per accedere ad un elemento è: <ArrayVariable>

Per esempio:
Se il tuo array è memorizzato nella variabile myArraye vuoi accedere al primo elemento (all’indice 0), useresti myArray

2️⃣ Memoria

Ora che sai come accedere ai valori, vediamo come gli array sono memorizzati nella memoria del tuo computer. Quando definisci la dimensione dell’array, tutto quello spazio in memoria è “riservato” da quel momento in poi per valori futuri che potresti voler inserire.

💡 Nota: Se non riempi l’array di valori, quello spazio sarà tenuto riservato e vuoto fino a quando non lo farai.

Per esempio:
Diciamo che definisci un array di dimensione 5 ma inserisci solo un valore. Tutto quello spazio rimanente sarà vuoto e “riservato” in memoria, in attesa di future assegnazioni.

Questa è la chiave perché gli array sono estremamente efficienti nell’accesso ai valori perché tutti gli elementi sono memorizzati in spazi contigui in memoria. In questo modo, il computer sa esattamente dove guardare per trovare le informazioni richieste.

Ma… c’è un lato negativo 😞 perché questo non è efficiente in termini di memoria. State riservando la memoria per operazioni future che potrebbero non verificarsi. Questo è il motivo per cui gli array sono raccomandati in situazioni in cui sai in anticipo quanti elementi stai per memorizzare.

🔧 Operazioni – Dietro le quinte!

Ora che sai cosa sono gli array quando vengono usati, e come immagazzinano gli elementi, ci immergeremo nelle loro operazioni come l’inserimento e la rimozione.

1️⃣ Inserimento – Benvenuto!

Diciamo che abbiamo un array di dimensione 6 e c’è ancora uno spazio vuoto. Vogliamo inserire un elemento “e” all’inizio dell’array (indice 0), ma questo posto è già occupato dall’elemento “a”. Cosa dobbiamo fare?

Per inserire negli array, spostiamo tutti gli elementi che si trovano a destra del luogo di inserimento, un indice a destra. L’elemento “a” sarà ora all’indice 1, l’elemento “b” sarà all’indice 2 e così via…

💡 Nota: dovrai creare una variabile per tenere traccia dell’ultimo indice che contiene elementi. Nel diagramma sopra, l’array è riempito fino all’indice 4 prima dell’inserimento. In questo modo, puoi determinare se l’array è pieno e quale indice dovresti usare per inserire un elemento alla fine.

Dopo aver fatto questo, il nostro elemento è inserito con successo. 👏

⚠️ Aspetta un attimo! Cosa succede se l’array è pieno?

Cosa pensi che succeda se l’array è pieno e cerchi di inserire un elemento? 😱

In questo caso, devi creare un nuovo array più grande e copiare manualmente tutti gli elementi in questo nuovo array. Questa operazione è molto costosa, in termini di tempo. Immaginate cosa accadrebbe se aveste un array con milioni di elementi! Questo potrebbe richiedere molto tempo per essere completato. ⏳

💡 Nota: L’unica eccezione a questa regola, quando l’inserimento è molto veloce, è quando inserisci un elemento alla fine dell’array (all’indice situato alla destra dell’ultimo elemento) e c’è ancora spazio disponibile. Questo avviene in tempo costante O(1).

2️⃣ Deletion- Bye, Bye!

Ora diciamo che vuoi cancellare un elemento dall’array.

Per mantenere l’efficienza dell’accesso casuale (poter accedere all’array attraverso un indice estremamente veloce) gli elementi devono essere memorizzati in spazi contigui di memoria. Non puoi semplicemente cancellare l’elemento e lasciare quello spazio vuoto.

Devi spostare gli elementi che vengono dopo l’elemento che vuoi cancellare di un indice a sinistra.

E infine, hai questo array risultante 👇. Come puoi vedere, “b” è stato cancellato con successo.

💡 Nota: La cancellazione è molto efficiente quando rimuovi l’ultimo elemento. Poiché è necessario creare una variabile per tenere traccia dell’ultimo indice che contiene elementi (nel diagramma sopra, l’indice 3), è possibile rimuovere direttamente quell’elemento usando l’indice.

3️⃣ Trovare un elemento

Hai tre opzioni per trovare un elemento in una matrice:

  • Se sai dove si trova, usa l’indice.
  • Se non sai dove si trova e i tuoi dati sono ordinati, puoi usare algoritmi per ottimizzare la tua ricerca, come la Ricerca Binaria.
  • Se non sai dove si trova e i tuoi dati non sono ordinati, dovrai cercare attraverso ogni elemento dell’array e controllare se l’elemento corrente è quello che stai cercando (vedi la sequenza di diagrammi sotto).

👋 In sintesi…

  • Gli array sono strutture dati estremamente potenti che memorizzano elementi dello stesso tipo. Il tipo di elementi e la dimensione dell’array sono fissi e definiti quando lo si crea.
  • La memoria viene allocata immediatamente dopo la creazione dell’array e rimane vuota finché non si assegnano i valori.
  • I loro elementi si trovano in posizioni contigue nella memoria, quindi si può accedere in modo molto efficiente (accesso casuale, O(1) = tempo costante) usando gli indici.
  • Gli indici iniziano da 0, non da 1 come siamo abituati.
  • Inserire elementi all’inizio o al centro dell’array comporta lo spostamento di elementi a destra. Se l’array è pieno, creare un nuovo array più grande (il che non è molto efficiente). Inserire alla fine dell’array è molto efficiente, tempo costante O(1).
  • Rimuovere elementi dall’inizio o dal centro dell’array comporta lo spostamento di tutti gli elementi a sinistra per evitare di lasciare uno spazio vuoto in memoria. Questo garantisce che gli elementi siano memorizzati in spazi contigui nella memoria. Rimuovere alla fine dell’array è molto efficiente perché si cancella solo l’ultimo elemento.
  • Per trovare un elemento, è necessario controllare l’intero array finché non lo si trova. Se i dati sono ordinati, puoi usare algoritmi come la ricerca binaria per ottimizzare il processo.

“Impara da ieri, vivi per oggi, spera per domani. L’importante è non smettere di domandare.”
– Albert Einstein

👋 Grazie!

Spero davvero che il mio articolo ti sia piaciuto. ❤️
Seguimi su Twitter per trovare altri articoli come questo. 😃

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.