un algoritm este o procedură specifică pentru rezolvarea unei probleme de calcul bine definite. Dezvoltarea și analiza algoritmilor este fundamentală pentru toate aspectele informaticii: inteligență artificială, baze de date, grafică, rețea, sisteme de operare, securitate și așa mai departe. Dezvoltarea algoritmului este mai mult decât programare., Necesită o înțelegere a alternativelor disponibile pentru rezolvarea unei probleme de calcul, inclusiv hardware-ul, rețeaua, limbajul de programare și constrângerile de performanță care însoțesc orice soluție particulară. De asemenea, necesită înțelegerea a ceea ce înseamnă ca un algoritm să fie „corect” în sensul că rezolvă pe deplin și eficient problema la îndemână.

o noțiune însoțitoare este proiectarea unei anumite structuri de date care permite unui algoritm să ruleze eficient., Importanța structurilor de date provine din faptul că memoria principală a unui computer (unde sunt stocate datele) este liniară, constând dintr-o secvență de celule de memorie care sunt numerotate în serie 0, 1, 2,…. Astfel, cea mai simplă structură de date este o matrice liniară, în care elementele adiacente sunt numerotate cu „indici” întregi consecutivi, iar valoarea unui element este accesată de indicele său unic. Un tablou poate fi folosit, de exemplu, pentru a stoca o listă de nume, și sunt necesare metode eficiente pentru a căuta în mod eficient și de a prelua un anumit nume din matrice., De exemplu, sortarea listei în ordine alfabetică permite utilizarea unei așa-numite tehnici de căutare binară, în care restul listei care trebuie căutate la fiecare pas este tăiat la jumătate. Această tehnică de căutare este similară cu căutarea unei cărți telefonice pentru un anumit nume. Știind că cartea este în ordine alfabetică, vă permite să vă întoarceți rapid la o pagină care este aproape de pagina care conține numele dorit. Mulți algoritmi au fost dezvoltați pentru sortarea și căutarea eficientă a listelor de date.,deși elementele de date sunt stocate consecutiv în memorie, ele pot fi legate între ele prin indicii (în esență, adresele de memorie stocate cu un element pentru a indica unde se găsesc următorul element sau elementele din structură), astfel încât datele să poată fi organizate în moduri similare cu cele în care vor fi accesate. Cea mai simplă astfel de structură se numește lista legată, în care elementele stocate necontigu pot fi accesate într-o ordine prestabilită urmând indicii de la un element din listă la altul., Lista poate fi circulară, ultimul element indicând primul sau fiecare element poate avea indicii în ambele direcții pentru a forma o listă dublu legată. Algoritmii au fost dezvoltați pentru manipularea eficientă a acestor liste prin căutarea, inserarea și eliminarea elementelor.indicii oferă, de asemenea, posibilitatea de a implementa structuri de date mai complexe. Un grafic, de exemplu, este un set de noduri (elemente) și legături (cunoscute sub numele de margini) care conectează perechi de elemente., Un astfel de grafic ar putea reprezenta un set de orașe și autostrăzi care le unește, dispunerea elementelor de circuit și conectarea firelor pe un cip de memorie sau configurația persoanelor care interacționează printr-o rețea socială. Tipic grafurilor include grafic de traversare strategii, cum ar fi cum să urmați link-urile de la nod la nod (probabil în căutarea pentru un nod cu o anumită proprietate) într-un mod care fiecare nod este vizitat doar o singură dată. O problemă conexă este determinarea celei mai scurte căi între două noduri date pe un grafic arbitrar. (Vezi teoria grafurilor.,) O problemă de interes practic pentru algoritmii de rețea, de exemplu, este de a determina câte legături „rupte” pot fi tolerate înainte ca comunicațiile să înceapă să eșueze. În mod similar, în proiectarea cipurilor de integrare la scară foarte mare (VLSI), este important să știm dacă graficul reprezentând un circuit este planar, adică dacă poate fi desenat în două dimensiuni fără traversarea legăturilor (atingerea firelor).complexitatea (computațională) a unui algoritm este o măsură a cantității de resurse de calcul (timp și spațiu) pe care un anumit algoritm le consumă atunci când rulează., Informaticienii folosesc măsuri matematice de complexitate care le permit să prezică, înainte de a scrie codul, cât de repede va rula un algoritm și câtă memorie va necesita. Astfel de predicții sunt ghiduri importante pentru programatorii care implementează și selectează algoritmi pentru aplicații din lumea reală.,complexitatea computațională este un continuum, prin faptul că unii algoritmi necesită timp liniar (adică timpul necesar crește direct cu numărul de elemente sau noduri din listă, grafic sau rețea procesate), în timp ce alții necesită timp pătratic sau chiar exponențial pentru a finaliza (adică timpul necesar crește cu numărul de elemente pătrat sau cu exponențialul acelui număr). La capătul îndepărtat al acestui continuum se află mările tulburi de probleme greu de rezolvat—cele ale căror soluții nu pot fi implementate eficient., Pentru aceste probleme, informaticienii încearcă să găsească algoritmi euristici care pot rezolva aproape problema și pot rula într-o perioadă rezonabilă de timp.

Mai departe sunt încă acele probleme algoritmice care pot fi declarate, dar nu sunt rezolvabile; adică se poate dovedi că niciun program nu poate fi scris pentru a rezolva problema. Un exemplu clasic al unei probleme algoritmice de nerezolvat este problema opririi, care afirmă că nu poate fi scris niciun program care să poată prezice dacă orice alt program se oprește sau nu după un număr finit de pași., Nesolvabilitatea problemei de oprire are o influență practică imediată asupra dezvoltării de software. De exemplu, ar fi frivol pentru a încerca să dezvolte un instrument software care prezice dacă un alt program dezvoltat are o buclă infinită în ea (deși având un astfel de instrument ar fi extrem de benefic).