Un algoritmo è una procedura specifica per risolvere un problema computazionale ben definito. Lo sviluppo e l’analisi di algoritmi è fondamentale per tutti gli aspetti dell’informatica: intelligenza artificiale, database, grafica, networking, sistemi operativi, sicurezza e così via. Lo sviluppo di algoritmi è più di una semplice programmazione., Richiede una comprensione delle alternative disponibili per risolvere un problema computazionale, incluso l’hardware, il networking, il linguaggio di programmazione e i vincoli di prestazioni che accompagnano qualsiasi soluzione particolare. Richiede anche la comprensione di cosa significa per un algoritmo essere “corretto” nel senso che risolve in modo completo ed efficiente il problema in questione.

Una nozione di accompagnamento è la progettazione di una particolare struttura di dati che consente a un algoritmo di funzionare in modo efficiente., L’importanza delle strutture dati deriva dal fatto che la memoria principale di un computer (in cui sono memorizzati i dati) è lineare, costituita da una sequenza di celle di memoria numerate in serie 0, 1, 2,…. Pertanto, la struttura dati più semplice è un array lineare, in cui gli elementi adiacenti sono numerati con “indici” interi consecutivi e il valore di un elemento è accessibile dal suo indice univoco. Un array può essere utilizzato, ad esempio, per memorizzare un elenco di nomi e sono necessari metodi efficienti per cercare e recuperare in modo efficiente un particolare nome dall’array., Ad esempio, l’ordinamento dell’elenco in ordine alfabetico consente di utilizzare una cosiddetta tecnica di ricerca binaria, in cui il resto dell’elenco da cercare ad ogni passaggio viene tagliato a metà. Questa tecnica di ricerca è simile alla ricerca di una rubrica telefonica per un nome particolare. Sapendo che il libro è in ordine alfabetico permette di girare rapidamente a una pagina che si trova vicino alla pagina contenente il nome desiderato. Molti algoritmi sono stati sviluppati per l’ordinamento e la ricerca di elenchi di dati in modo efficiente.,

Sebbene gli elementi di dati siano memorizzati consecutivamente in memoria, possono essere collegati tra loro da puntatori (essenzialmente, indirizzi di memoria memorizzati con un elemento per indicare dove si trovano l’elemento successivo o gli elementi nella struttura) in modo che i dati possano essere organizzati in modi simili a quelli in cui saranno accessibili. La struttura più semplice di questo tipo è chiamata elenco collegato, in cui è possibile accedere agli elementi memorizzati in modo non contiguo in un ordine pre-specificato seguendo i puntatori da un elemento dell’elenco a quello successivo., L’elenco può essere circolare, con l’ultimo elemento che punta al primo, o ogni elemento può avere puntatori in entrambe le direzioni per formare una lista doppiamente collegata. Sono stati sviluppati algoritmi per manipolare in modo efficiente tali elenchi cercando, inserendo e rimuovendo elementi.

I puntatori offrono anche la possibilità di implementare strutture dati più complesse. Un grafico, ad esempio, è un insieme di nodi (elementi) e collegamenti (noti come bordi) che collegano coppie di elementi., Tale grafico potrebbe rappresentare un insieme di città e le autostrade che le uniscono, il layout degli elementi del circuito e i fili di collegamento su un chip di memoria, o la configurazione di persone che interagiscono tramite un social network. Gli algoritmi tipici del grafico includono strategie di attraversamento del grafico, come il modo di seguire i collegamenti da nodo a nodo (magari cercando un nodo con una particolare proprietà) in modo che ogni nodo venga visitato una sola volta. Un problema correlato è la determinazione del percorso più breve tra due nodi dati su un grafico arbitrario. (Vedi teoria dei grafi.,) Un problema di interesse pratico negli algoritmi di rete, ad esempio, è determinare quanti collegamenti “interrotti” possono essere tollerati prima che le comunicazioni inizino a fallire. Allo stesso modo, nella progettazione di chip VLSI (very-large-Scale Integration) è importante sapere se il grafico che rappresenta un circuito è planare, cioè se può essere disegnato in due dimensioni senza collegamenti che attraversano (fili che toccano).

La complessità (computazionale) di un algoritmo è una misura della quantità di risorse di calcolo (tempo e spazio) che un particolare algoritmo consuma quando viene eseguito., Gli informatici utilizzano misure matematiche di complessità che consentono loro di prevedere, prima di scrivere il codice, quanto velocemente un algoritmo verrà eseguito e quanta memoria richiederà. Tali previsioni sono guide importanti per i programmatori che implementano e selezionano algoritmi per applicazioni reali.,

la complessità Computazionale è un continuum, che alcuni algoritmi richiede tempo lineare (che è, il tempo necessario aumenta direttamente con il numero di elementi o nodi nella lista, grafico, o di rete in fase di elaborazione), mentre altri richiedono quadratica o addirittura esponenziale tempo per completare (che è, il tempo necessario aumenta con l’aumentare del numero di elementi squadrati o con l’esponenziale del numero). Alla fine di questo continuum si trovano i mari torbidi di problemi intrattabili—quelli le cui soluzioni non possono essere attuate in modo efficiente., Per questi problemi, gli informatici cercano di trovare algoritmi euristici che possono quasi risolvere il problema ed eseguire in un ragionevole lasso di tempo.

Più lontano ci sono ancora quei problemi algoritmici che possono essere dichiarati ma non sono risolvibili; cioè, si può dimostrare che nessun programma può essere scritto per risolvere il problema. Un classico esempio di un problema algoritmico irrisolvibile è il problema di arresto, che afferma che nessun programma può essere scritto in grado di prevedere se un altro programma si arresta o meno dopo un numero finito di passaggi., L’irrisolvibilità del problema di arresto ha un impatto pratico immediato sullo sviluppo del software. Ad esempio, sarebbe frivolo cercare di sviluppare uno strumento software che predica se un altro programma in fase di sviluppo ha un ciclo infinito in esso (anche se avere un tale strumento sarebbe immensamente vantaggioso).