Análise e Complexidade de Algoritmos Professor Ariel da Silva Dias Insertion Sort
Introdução Existem modos diferentes para realizar uma ordenação e, nas próximas aulas, continuaremos estudando cada uma delas O segundo algoritmo que estudaremos é o
Imagine o seguinte caso: você está jogando baralho e as cartas estão ordenadas
Imagine o seguinte caso: você está jogando baralho e as cartas estão ordenadas Você recebe uma nova carta e você deve coloca-la na posição correta, de forma que as cartas continuem ordenadas A nova carta pode ser menor que alguma das cartas que você está segurando
Sua ação para inseri-la ao meio de suas cartas: Você examina as cartas que já possui, comparando a nova carta com todas que estão em sua mão, até encontrar uma posição para coloca-la
Sua ação para inseri-la ao meio de suas cartas: Você examina as cartas que já possui, comparando a nova carta com todas que estão em sua mão, até encontrar uma posição para coloca-la
Sua ação para inseri-la ao meio de suas cartas: Você examina as cartas que já possui, comparando a nova carta com todas que estão em sua mão, até encontrar uma posição para coloca-la
Você insere a nova carta na posição correta e, novamente, sua mão é composta por cartas totalmente ordenadas E quando você receber outra carta você repetirá o mesmo procedimento...
Este é o funcionamento do algoritmo Percorre o array começando com índice 1 Cada nova posição é como a nova carta que você recebeu Você pode inseri-la no lugar correto no subarray, ordenando à esquerda daquela posição
0 1 2 3 4
Inspeciona a carta do índice 1 e armazena em um local temporário 0 1 2 3 4
Move a carta para a direita para abrir espaço à carta armazenada 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Inspeciona a carta no índice 2 0 1 2 3 4
Como esta carta é menor que as demais, armazena ela em um local temporário e desloca as cartas da esquerda para a direita 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Inspeciona a carta no índice 3 0 1 2 3 4
Como esta carta é menor que as demais, armazena ela em um local temporário e desloca as cartas da esquerda para a direita 0 1 2 3 4
Como esta carta é menor que as demais, armazena ela em um local temporário e desloca as cartas da esquerda para a direita 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Inspeciona a carta no índice 4 0 1 2 3 4
Move as cartas a direita para abrir espaço correto para a carta armazenada 0 1 2 3 4
Move as cartas a direita para abrir espaço correto para a carta armazenada 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Coloca a carta armazenada no local final correto 0 1 2 3 4
Imagine que o array do índice 0 ao 5 já está ordenado, e queremos inserir um novo elemento neste array, de forma que ele fique ordenado 0 1 2 3 4 5 50 56 59 62 64 52 Para isso, temos que comparar o elemento do índice 5 (número 52) com todos os elementos a esquerda, indo da direita para a esquerda
Vamos a partir de agora chamar o elemento na posição 5 de chave Sempre que descobrirmos que a chave é menor que um elemento à sua esquerda, descolamos esse elemento para a posição a direita, uma vez que a chave deve ficar a esquerda deste elemento Precisamos fazer 2 coisas: precisamos de uma operação de deslocamento que mova um elemento uma posição para a direita; precisamos salvar o valor da chave em uma posição separada, evitando que ela seja sobrescrita 0 1 2 3 4 5 50 56 59 62 64 52
No nosso exemplo, vamos armazenar o valor do índice 5 em uma variável chamada key KEY 52 0 1 2 3 4 5 50 56 59 62 64 52
Vamos agora comparar key com o elemento no índice 4 key é menor que o valor do elemento no índice 4 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 4 para o índice 5 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 62 64 52
Vamos agora comparar key com o elemento no índice 4 key é menor que o valor do elemento no índice 4 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 4 para o índice 5 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 62 64 64
Vamos agora comparar key com o elemento no índice 3 key é menor que o valor do elemento no índice 3 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 4 para o índice 5 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 62 64 64
Vamos agora comparar key com o elemento no índice 3 key é menor que o valor do elemento no índice 3 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 3 para o índice 4 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 62 62 64
Vamos agora comparar key com o elemento no índice 2 key é menor que o valor do elemento no índice 2 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 2 para o índice 3 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 62 62 64
Vamos agora comparar key com o elemento no índice 2 key é menor que o valor do elemento no índice 2 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 2 para o índice 3 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 59 62 64
Vamos agora comparar key com o elemento no índice 1 key é menor que o valor do elemento no índice 1 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 1 para o índice 2 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 59 59 62 64
Vamos agora comparar key com o elemento no índice 1 key é menor que o valor do elemento no índice 1 então vamos deslocar este elemento para a direita note que esta operação simplesmente copia o valor do índice 1 para o índice 2 (uma posição para a direita) KEY 52 0 1 2 3 4 5 50 56 56 59 62 64
Vamos agora comparar key com o elemento no índice 0 key é maior que o valor do elemento no índice 0 agora não teremos deslocamento agora vamos colocar o valor de key imediatamente na posição a direita deste elemento KEY 52 0 1 2 3 4 5 50 56 56 59 62 64
Vamos agora comparar key com o elemento no índice 0 key é maior que o valor do elemento no índice 0 agora não teremos deslocamento agora vamos colocar o valor de key imediatamente na posição a direita deste elemento KEY 52 0 1 2 3 4 5 50 52 56 59 62 64
O resultado agora é um array ordenado 0 1 2 3 4 5 50 52 56 59 62 64
Quando a chave sendo inserida for menor que todos os elementos à sua esquerda todos os elementos no array à esquerda da chave se deslocam uma posição para a direita devemos parar quando chegarmos à extremidade esquerda do array
Quando a chave é maior ou igual a todos os elementos à sua esquerda na primeira comparação já descobrimos que a chave está na sua posição correta em relação a todos os elementos à sua esquerda nenhum elemento é deslocado e a chave retorna à posição que começou
- pseudocódigo para i até 4 faça inicio chave vetor[i] j i 1 enquanto(j >= 0 E vetor[j] > chave) inicio vetor[j+1] x[j] j j-1 fim vetor[j+1] chave fim
L Código Custo Vezes 1 para i até 4 faça C1 n 2 inicio 0 0 3 chave vetor[i] C2 n-1 4 j i 1 C3 n-1 5 enquanto(j >= 0 E vetor[j] > chave) C4 n tj j=2 6 inicio 0 7 vetor[j+1] x[j] C5 8 j j-1 C6 n tj 1 j=2 n tj 1 9 fim 0 0 10 vetor[j+1] chave C7 n-1 11 fim j=2
Análise da Complexidade Como vimos com no Bubble Sort, o tempo de execução do algoritmo é a soma dos tempos de execução para cada instrução executada; Uma instrução que demanda ci passos para ser executada e é executada n vezes, contribuirá com ci.n para o tempo de execução total; No teremos o melhor e pior caso, calcularemos primeiro o melhor caso, ou seja, quando o vetor estiver 100% ordenado
Análise da Complexidade (Melhor Caso) T n = c1 n + c2 n 1 + c3 n 1 + c7 (n 1) T n = c1 n + c2 n c2 + c3 n c3 + c7 n c3 T n = c1 + c2 + c3 + c7 n c2 + c3 + c7 T n = an b Podemos dizer que, no melhor caso, a função custo de complexidade do algoritmo é f(n)=an-b, ou O(n)
Análise da Complexidade Se o vetor estiver ordenado de forma decrescente, teremos o pior caso Devemos comparar cada elemento do vetor, com cada elemento do subvetor ordenado inteiro A seguir é apresentado o cálculo da complexidade
Análise da Complexidade (Pior Caso) T n = c1 n + c2 n 1 + c3 n 1 + c7 n 1 + c4 n n 1 2 + c7 n 1 = T n = c1 n + c2 n c2 + c3 n c3 + c7 n c3 + c4 n2 n T n = c4+c5+c6 2 n 2 + c1+c2+c3+c7+c4+c5+c6 2 n n 1 n (c2 + c3 + c4 + c5 + c6)= 2 2 1 + c5 1 + c5 n2 n 2 n n 1 2 + c6 + c6 n2 n 2 = T n = an 2 + bn + c Podemos dizer que, no pior caso, a função custo de complexidade do algoritmo é f(n)=an²+bn-c, ou O(n²)