TS implementada com busca binária

Livro de Sedgewick e Wayne: sec.3.1, p.362.  Website do livro: resumo sec.3.1, slides.  Código fonte, documentação, e dados de teste de todos os programas do livro: veja algs4.cs.​princeton.edu/​code/.

Resumo:

Pré-requisitos:

TSs ordenadas

Exercícios 1

  1. Escreva um método recursivo limpa() que receba um vetor crescente a[0..n-1] e elimine os elementos repetidos do vetor, deixando o resultado limpo em a[0..m-1].

Implementação de TS em vetor ordenado

Exercícios 2

  1. [!] No livro de SW (p.379), a primeira linha do código de get() diz
          if (isEmpty()) return null;
    
    Isso é necessário?
  2. Escreva uma implementação do método contains().
  3. Implemente o método Iterable<Key> keys().
  4. (SW 3.1.25) Caching em software. A implementação padrão de contains() chama get(). Assim, o loop interno
         if (!st.contains(word)) st.put(word, 1);
         else st.put(word, st.get(word) + 1);
    

    de FrequencyCounter resulta em duas ou três buscas para a mesma chave. Para evitar isso sem mudar o código de FrequencyCounter, podemos usar a técnica de software caching: armazenamos a localização da chave mais recentemente encontrada em uma variável de instância. Faça isso em BinarySearchST.

  5. (SW 3.1.3)  Escreva uma implementação OrderedSequentialSearchST de TS baseado em um lista ligada ordenada. Quais as vantagens e desvantages?

Desempenho de BinarySearchST

Exercícios 3

  1. (SW 3.1.15)  Suponha que buscas são 1000 vezes mais frequentes que inserções em um cliente de BinarySearchST. Estimate a porcentagem do tempo total que é gasta em inserções quando o número de buscas é 103, 106, e 109.
  2. (SW 3.1.28) Inserções ordenadas. Modifique BinarySearchST de modo que a inserção de uma chave maior que todas as que estão na TS consuma tempo constante (de modo a construção de uma TS a partir de dados que estão em ordem crescente consuma tempo linear).
  3. Acrescente um método a BinarySearchBST que calcule o custo médio de uma busca bem-sucedida, supondo que todas as chave têm a mesma probabilidade de ser buscada.
  4. Acrescente um método a BinarySearchST que calcule o custo médio de uma busca malsucedida (supondo que todos os intervalos entre chaves da TS são igualmente prováveis).
  5. (SW 3.1.38, p.394) Gráficos de custo amortizado. Aparelhe FrequencyCounter e BinarySearchST para produzir gráficos como os vistos acima (eles mostram o custo de cada put() ao longo da computação).
  6. (SW 3.1.39, p.394) Tempo real.  Aparelhe FrequencyCounter com Stopwatch e StdDraw para fazer um gráfico em que o eixo x corresponde às sucessivas chamadas de get() e put() e o eixo y é o tempo total de execução. Um ponto é marcado no gráfico para representar o tempo acumulado depois de cada chamada. Rode o seu programa com tale.txt usando BinarySearchST. Discuta os resultados. (Observação: Saltos acentuados na curva podem ser explicados pelo caching, coisa que está além do escopo deste exercício.)

Resumo

Exercícios 4

  1. (SW 3.1.13)  Qual das implementações de TS você usaria para uma aplicação que faz 103 puts e 106 gets, misturadas aleatoriamente?
  2. (SW 3.1.14)  Qual das implementações de TS você usaria para uma aplicação que faz 106 puts e 103 gets, misturadas aleatoriamente?
  3. (SW 3.1.31 simplificado) Testes de desempenho. Escreva um programa que preencha uma TS com N chaves aleatórias e depois faça buscas aleatórias de modo que cada chave na TS seja encontrada (busca bem-sucedida) aproximadamente 10 vezes e haja aproximadamente o mesmo número de buscas malsucedidas. Repita o experimento muitas vezes, dobrando o valor de N sucessivamente. Meça o tempo de cada experimento e imprima um gráfico do crescimento do tempo médio em função de N.

Perguntas e respostas