Visão Geral
O livro consiste em 11 capítulos, embora o primeiro seja mais uma introdução (intitulado "Conhecendo Algoritmos"), e o último trate mais sobre o que pode (e idealmente deveria) ser estudado a seguir, assim como tópicos que este livro não cobre completamente (como MapReduce, filtro de Bloom, SHA e outros). Então, o que este livro aborda? Vamos dar uma olhada.
Primeiramente, o livro menciona a complexidade dos algoritmos e a chamada notação "Big O". E acredite, a grande maioria dos cursos de programação ensina habilidades muito específicas, mas raramente falam sobre complexidade de tempo de execução ou otimização de código.
Quanto aos tópicos abordados, vou listá-los rapidamente neste parágrafo.
O livro começa com um capítulo sobre arrays e listas encadeadas, explicando como trabalhar com eles (em termos de ordenação e busca). São listadas as vantagens e desvantagens das listas (do ponto de vista de velocidade de leitura/escrita e armazenamento de dados).
Em seguida há um capítulo curto sobre recursão, abordando a pilha de chamadas e seu funcionamento.
Depois, o livro mergulha no algoritmo quicksort (usando a abordagem "dividir para conquistar"). Para reforçar o entendimento dessa abordagem, o autor fornece três exemplos. O elemento pivô é discutido, e comparações de desempenho entre diferentes métodos de ordenação (incluindo os de capítulos anteriores) são ilustradas com gráficos.
A seção seguinte introduz um novo tipo de dado - ou melhor, uma estrutura fundamental - as tabelas hash. São descritos cenários onde elas são úteis (por exemplo, eliminação de duplicatas, cache, modelagem de relações entre objetos). Casos de colisão também são explicados.
Logo após, o livro introduz grafos como estrutura de dados. Não, não cobre todos os tópicos que estudei em "Modelagem Matemática", mas pelo menos aborda o básico: o que é um grafo, seu propósito, aplicações e grafos direcionados vs. não direcionados. E como grafos tratam de "caminhos", os algoritmos cobertos incluem busca em largura (BFS) e como encontrar o caminho mais curto. Este capítulo também menciona filas e revisa pilhas, explicando FIFO e LIFO - embora, na minha opinião, isso deveria ter sido abordado antes. A propósito, dois capítulos são dedicados a grafos. Se o primeiro trata de encontrar o caminho mais curto em grafos não ponderados, o segundo foca em grafos ponderados usando o algoritmo de Dijkstra. Novamente, vários exemplos são incluídos: primeiro abstratos, depois em código. O algoritmo Bellman-Ford (para grafos com arestas de peso negativo) não é coberto e fica para estudo independente.
No final, o livro aborda problemas e algoritmos menos comuns (na programação do dia a dia). Por exemplo, discute algoritmos gulosos (greedy), abordagens para problemas "impossíveis" sem solução algorítmica rápida (problemas NP-completos), programação dinâmica (quebrar problemas complexos em subproblemas) e o algoritmo k-vizinhos mais próximos (k-NN) usado em aprendizado de máquina.
Características
O livro inclui ilustrações que ajudam a visualizar e complementar o material. Cada capítulo também contém entre 5 e 7 perguntas práticas. A maioria é conceitual (embora algumas incluam código), e as respostas são fornecidas no final para autoavaliação. Cada capítulo termina com um "resumo rápido" - um resumo em 4 ou 5 frases.
O livro tem cerca de 300 páginas, e os capítulos são concisos, então é muito provável que quem começar irá terminar. É fácil e rápido de ler.
Conclusão
Um livro excelente para quem entrou na programação sem formação técnica. Explica vários métodos de ordenação e busca (busca binária, busca em profundidade e em largura) em termos simples. Aborda o tópico crucial da complexidade algorítmica ("Big O"). Inclui até mesmo material sobre grafos, algoritmos de caminhos mais curtos, k-vizinhos mais próximos e outros tópicos fundamentais que todo programador deveria conhecer, pelo menos no nível básico.