Informática, perguntado por JuGracini, 1 ano atrás

Gente, alguém por favor me ajuda! Estou tentando escrever um código do algoritmo de bubblesort. O conceito do bubble é trocar de valores entre posições consecutivas, para que fiquem ordenados. E eu não tenho ideia do que eu estou errando no meu algoritmo.
OBS: Só posso usar a biblioteca "#include
#include

void troca (int *a, int *b)
{
int aux;

aux = *a;
*a = *b;
*b = aux;
}
int main ()
{
int v[100];
int i,j,num,tam;

scanf ("%i", &num);

for (i = 0; i < num;i++)
{
scanf ("%i", &v[i]);
}
tam = num;
for (i = 0;i < tam;i++)
{
for (j = 0; j < tam;j++)
{
if (v[j] > v[j+1])
{
troca (&v[j], &v[j+1]);
}
}
}
}

Soluções para a tarefa

Respondido por bokomoko
0
tem um erro fundamental no seu programa. E duas coisas que seu programa poderia fazer melhor

Primeiro vamos para o erro fundamental que está aqui

for (j = 0; j < tam;j++)

Esse é o segundo for do bubblesort. Observe que o j vai variar de 0 a tam (o tamanho do vetor só que dentro do loop você faz a seguinte comparação
if (v[j] > v[j+1])

Ora, se j vai chegar até o tamanho do vetor, então j+1 vai ALËM do tamanho do vetor. O que acontece aí é o que se chama de "erro de subscrito". Seu programa está acessando a posiçao da memória seguinda ao último elemento do vetor. O que acontece é bizarro. Se o valor lá por acaso for considerado um inteiro negativo, esse valor vai ser deslocado para a primeira posição do vetor e deslocará um dos elementos válidos do vetor para FORA do vetor sujando o conteúdo da variável seguinte. Por acaso o valor da variável i inteira (depende do compilador). Por acaso a variável i é a indexadora do primeiro for, aí fica o samba do crioulo doido.  A linguagem C não detecta erro de subscrito em tempo de execução. Diferente do Pascal ou mesmo do Visual Basic ou do Python. O programa em C está por conta do programador. Nesse caso, um erro catastrófico pode acontecer. Graças aos deuses dos bits e bytes que os sistemas operacionais de memória protegida ainda estão por aí. ... Esse comando for TEM que ser alterado para ficar assim
for (j = 0; j < tam-1;j++)

Essa modificação simples salva o programa e ele vai se tornar funcional.

Mas ... tem espaço para melhorá-lo ainda. aliás, muito espaço.

Primeiro, eu recomendaria que você imprimisse a matriz depois de ler os dados e ANTES de fazer a ordenação. Para mostrar que o programa funcionou. Eis a rotina para imprimir bacaninha
void imprime( int a[] ) {  int i;  for (i=0;i<100;i++){    printf("%4d",a[i]);    if (!((i+1)%10)) {      printf("\n");    };  };  printf("\n");  }função para você chamar duas vezes. Uma depois de ler os dados e antes de começar o bubble sort e outra depois do bubblesort.

Segunda dica:
Você criou uma variável num e uma variável tam. Não precisa da variável tam. Ela faz exatamente a mesma coisa que a variável num.

Terceira dica:
O bubble sorte é conhecido como um algoritmo fácil de implementar porém muito ruim de performance. Ele é do tipo O(n²). Algoritmos eficientes são do tipo O(n log n), que é mais ou menos o número de comparações que são feitas para obter o vetor ordenado. n² é muito maior que n log n. Mesmo sendo ruim, podemos melhorar o bubble sort.

Você está comparando v[x] com v[x] , n vezes, desnecessariamente. Isso acontece porque o segundo loop começa do j=0, se j começasse de i+1 você economiza essa comparação. Isso vai fazer com que o número de comparações será sempre n * n. Ou seja, para ordenar um vetor de 100 posiçòes vai fazer 10 mil comparações !!!


 Se modificar para essa versão aqui, em média vai reduzir para 65% do número de comparações. Além disso, se o vetor já estiver ordenado, ou perto de ficar ordenado, ele vai terminar bem mais rápido. O pior cenário seria encontrar o vetor totalmente invertido, aí dá as mesmas 100*100 comparações. É uma situação extremamente rara.

  int falhou=0;
  do {
    falhou=0;
    for (j=0;j<tam-1;j++){
      if (v[j] > v[j+1]) {
        troca (&v[j], &v[j+1]);
        falhou = 1;
      };
    }
  } while (falhou);

Se quiser ver o programa completo, está aqui 
https://repl.it/@bokomoko/velho-buble-sort-de-guerra
Perguntas interessantes