Aula 34 – Busca Sequencial: com e sem Sentinela

Duas formas de procurar um elemento na lista — e um truque clássico para otimizar o loop de busca

Busca Sequencial — A Ideia

A busca mais simples possível: percorrer a lista do início ao fim, comparando cada elemento com a chave procurada. Se encontrar, retorna o índice. Se chegar ao final sem encontrar, retorna ERRO.

A busca sequencial (ou busca linear) percorre os elementos um a um em ordem. Não exige que a lista esteja ordenada. Tem complexidade O(n) — no pior caso, examina todos os n elementos.

Comparação direta com Java:

OperaçãoC (nossa lista)Java (ArrayList)
Busca por valor buscaSequencial(&lista, 4) → retorna índice ou -1 lista.indexOf(4) → retorna índice ou -1
Algoritmo interno Explícito — você escreve o while Oculto — ArrayList faz internamente
Exige lista ordenada? Não Não
Complexidade O(n) O(n)

Versão 1 — Busca Sequencial sem Sentinela

Esta é a implementação direta e natural:

int buscaSequencial(LISTA* l, TIPOCHAVE ch) {
    int i = 0;
    while (i < l->nroElem) {
        if (ch == l->A[i].chave) return i;  // achou — retorna o índice
        else i++;
    }
    return ERRO;  // não achou — retorna -1
} /* buscaSequencial */

A cada iteração do while, o loop faz duas verificações:

Verificação 1 (limite):
i < l->nroElem

Garante que não passamos do final da lista.
Verificação 2 (chave):
ch == l->A[i].chave

Verifica se encontramos o elemento.

Para uma lista com n elementos onde a chave não existe, são feitas 2n comparações no total. É aqui que entra a otimização com sentinela.

Versão 2 — Busca Sequencial com Sentinela

A ideia é elegante: colocamos a própria chave procurada na posição A[nroElem] (a posição "extra" que reservamos com MAX+1). Isso garante que a chave sempre será encontrada em algum ponto — então o while não precisa mais verificar o limite!

int buscaSentinela(LISTA* l, TIPOCHAVE ch) {
    int i = 0;
    l->A[l->nroElem].chave = ch;  // coloca a sentinela na posição extra

    while (l->A[i].chave != ch) i++;  // uma única verificação por iteração!

    if (i > l->nroElem - 1) return ERRO;  // parou na sentinela — não achou
    else return i;                          // parou antes — achou de verdade
} /* buscaSentinela */
Como a sentinela funciona: Se a chave existe na lista, o while para nessa posição (antes de nroElem). Se não existe, o while para na sentinela (posição nroElem). Em ambos os casos, o loop sempre termina — sem precisar verificar i < nroElem.

Comparação lado a lado

Sem sentinelaCom sentinela
Verificações por iteração 2 (limite + chave) 1 (só chave)
Condição do while i < nroElem && A[i] != ch A[i] != ch
Exige posição extra no array? Não — funciona com A[MAX] Sim — exige A[MAX+1]
Complexidade O(n) O(n)
Velocidade prática Base Ligeiramente mais rápida (metade das comparações)
Exige lista ordenada? Não Não
Sentinela não é busca binária! Ambas as versões continuam sendo O(n) — percorrem um elemento por vez. A diferença é apenas uma otimização de constante: menos comparações por iteração. Busca binária (Aula 35) tem complexidade O(log n) — mas exige lista ordenada.

Exemplo Completo de Uso

int main() {
    LISTA lista;
    inicializarLista(&lista);

    REGISTRO reg;
    reg.chave=9;  inserirElemLista(&lista, reg, 0);
    reg.chave=3;  inserirElemLista(&lista, reg, 1);
    reg.chave=4;  inserirElemLista(&lista, reg, 2);
    reg.chave=1;  inserirElemLista(&lista, reg, 3);
    reg.chave=12; inserirElemLista(&lista, reg, 2);  // insere 12 na posição 2

    exibirLista(&lista);
    // Lista: " 9 3 12 4 1 "

    printf("Busca por 4 (sem sentinela): posição %d\n",
           buscaSequencial(&lista, 4));
    printf("Busca por 4 (com sentinela): posição %d\n",
           buscaSentinela(&lista, 4));
    printf("Busca por 99 (inexistente):  posição %d\n",
           buscaSequencial(&lista, 99));

    return 0;
}

Lista: " 9 3 12 4 1 "

Busca por 4 (sem sentinela): posição 3

Busca por 4 (com sentinela): posição 3

Busca por 99 (inexistente): posição -1

Exercícios — Aula 34

1. Qual é a complexidade da busca sequencial sem sentinela para uma lista de n elementos?

2. Por que a busca com sentinela não precisa verificar i < nroElem dentro do while?

3. Onde a sentinela é colocada e por que isso exige A[MAX+1]?

4. A busca com sentinela encontrou o elemento na posição i = nroElem. O que isso significa?

5. A busca com sentinela é mais rápida que a busca binária?

6. Qual função do Java é conceitualmente mais próxima de buscaSequencial(&lista, 4)?

7. A busca sequencial (sem sentinela) exige que a lista esteja ordenada?

8. Analise o código da busca sem sentinela. Se a lista tem nroElem=0 e chamamos buscaSequencial, o que acontece?