an algorithm is a specific procedure for solving a well-defined computational problem. O desenvolvimento e análise de algoritmos é fundamental para todos os aspectos da ciência da computação: inteligência artificial, bases de dados, gráficos, redes, sistemas operacionais, segurança, etc. O desenvolvimento de algoritmos é mais do que apenas programação., Requer uma compreensão das alternativas disponíveis para resolver um problema computacional, incluindo o hardware, rede, linguagem de programação e restrições de desempenho que acompanham qualquer solução em particular. Ele também requer compreensão do que significa para um algoritmo ser “correto” no sentido de que ele resolve o problema em mãos de forma completa e eficiente.

uma noção que a acompanha é o desenho de uma estrutura de dados particular que permite que um algoritmo execute eficientemente., A importância das estruturas de dados deriva do fato de que a memória principal de um computador (onde os dados são armazenados) é linear, consistindo de uma sequência de células de memória que são numeradas sequencialmente 0, 1, 2,…. Assim, a estrutura de dados mais simples é uma matriz linear, na qual os elementos adjacentes são numerados com “índices” inteiros consecutivos e o valor de um elemento é acessado por seu índice único. Um array pode ser usado, por exemplo, para armazenar uma lista de nomes, e métodos eficientes são necessários para eficientemente procurar e recuperar um nome particular do array., Por exemplo, classificar a lista em ordem alfabética permite que uma chamada técnica de busca binária seja usada, na qual o restante da lista a ser pesquisada em cada passo é cortado ao meio. Esta técnica de busca é semelhante à busca de uma lista telefônica para um nome particular. Saber que o livro está em ordem alfabética permite que se vire rapidamente para uma página que está perto da página que contém o nome desejado. Muitos algoritmos foram desenvolvidos para classificar e pesquisar listas de dados de forma eficiente.,

Embora os itens de dados são armazenados consecutivamente na memória, eles podem ser ligados entre si através de ponteiros (essencialmente, endereços de memória armazenado com um item para indicar onde o próximo item ou itens na estrutura são encontrados), de modo a que os dados podem ser organizados em formas semelhantes àquelas em que eles serão acessados. A estrutura mais simples é chamada de lista vinculada, na qual itens não contiguosamente armazenados podem ser acessados em uma ordem pré-especificada, seguindo os ponteiros de um item na lista para o próximo., A lista pode ser circular, com o último item apontando para o primeiro, ou cada elemento pode ter ponteiros em ambas as direções para formar uma lista duplamente ligada. Algoritmos têm sido desenvolvidos para manipular eficientemente tais listas, procurando, inserindo e removendo itens.ponteiros

também fornecem a capacidade de implementar estruturas de dados mais complexas. Um grafo, por exemplo, é um conjunto de nós (itens) e links (conhecidos como arestas) que conectam pares de itens., Tal grafo pode representar um conjunto de cidades e as rodovias que os unem, o layout de elementos de circuito e Fios de conexão em um chip de memória, ou a configuração de pessoas interagindo através de uma rede social. Algoritmos de grafos típicos incluem estratégias transversais de grafos, como como seguir as ligações de nó para nó (talvez procurando por um nó com uma propriedade particular) de uma forma que cada nó é visitado apenas uma vez. Um problema relacionado é a determinação do caminho mais curto entre dois nós em um grafo arbitrário. (See graph theory., Um problema de interesse prático em algoritmos de rede, por exemplo, é determinar quantas ligações “quebradas” podem ser toleradas antes que as comunicações comecem a falhar. Da mesma forma, no design de chip de integração em grande escala (VLSI) é importante saber se o grafo que representa um circuito é planar, ou seja, se ele pode ser desenhado em duas dimensões sem qualquer cruzamento de ligações (fios tocando).

a complexidade (computacional) de um algoritmo é uma medida da quantidade de recursos de computação (tempo e espaço) que um algoritmo particular consome quando ele roda., Os cientistas da computação usam medidas matemáticas de complexidade que lhes permitem prever, antes de escrever o código, a rapidez com que um algoritmo corre e a quantidade de memória necessária. Tais previsões são guias importantes para programadores implementando e selecionando algoritmos para aplicações do mundo real.,

complexidade Computacional é um continuum, em que alguns algoritmos requerem tempo linear (isto é, o tempo necessário aumenta diretamente com o número de itens ou nós na lista, gráfico, ou rede que está sendo processada), enquanto que outros requerem quadrática ou exponencial mesmo tempo para concluir (isto é, o tempo necessário aumenta com o número de itens quadrado ou com o exponencial do número). No final deste continuum encontram—se os mares turvos de problemas intratáveis-aqueles cujas soluções não podem ser eficazmente implementadas., Para estes problemas, os cientistas da computação procuram encontrar algoritmos heurísticos que podem quase resolver o problema e executar em uma quantidade razoável de tempo.

ainda mais longe estão os problemas algorítmicos que podem ser declarados mas não podem ser resolvidos; ou seja, pode-se provar que nenhum programa pode ser escrito para resolver o problema. Um exemplo clássico de um problema algorítmico insolúvel é o problema da parada, que afirma que nenhum programa pode ser escrito que possa prever se qualquer outro programa pára ou não após um número finito de passos., A impossibilidade de resolver o problema da Parada tem um impacto prático imediato no desenvolvimento de software. Por exemplo, seria frívolo tentar desenvolver uma ferramenta de software que prevê se outro programa que está sendo desenvolvido tem um laço infinito nele (embora ter tal ferramenta seria imensamente benéfico).