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
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
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
Ed. Física,
8 meses atrás
Artes,
8 meses atrás
Geografia,
8 meses atrás
Matemática,
1 ano atrás
Português,
1 ano atrás
Português,
1 ano atrás