Gman9 Posted October 20, 2016 at 05:28 PM Report #599774 Posted October 20, 2016 at 05:28 PM Boas pessoal alguém consegue me ajudar a perceber o seguinte... Considerando a implementação recursiva do algoritmo de ordenação merge sort. Para um array de dimensão 2^n, qual o número de vezes que a função merge é chamada? static void mergesort(int [] a, int l, int r){ if (l < r) { int m = (l+r)>>>1; mergeSort(a, l, m); mergeSort(a, m+1, r); merge(a, l, m, r); } }
HappyHippyHippo Posted October 20, 2016 at 09:49 PM Report #599782 Posted October 20, 2016 at 09:49 PM a ideia do algoritmo merge sort recai em dividir a lista em elementos mais pequenos (a metade) e fazer o "merge" (junção ordenada) dessas listas (já ordenadas pela recursividade) se o algoritmo recai em dividir em metade, então em cada chamada, se tens uma lista de 2^n elementos, ficas com duas listas de 2^(n-1) elementos, às quais terás de chamar a função recursivamente. O que pretendes saber é na realidade o que se chamada de complexidade no tempo do algoritmo, que é de n*log(n), onde n é o número de elementos Sendo assim, o número de vezes que a função é chamada para uma lista de 2^n é de (2^n)*log(2^n) 1 Report IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Rui Carlos Posted October 20, 2016 at 10:54 PM Report #599783 Posted October 20, 2016 at 10:54 PM 1 hora atrás, HappyHippyHippo disse: O que pretendes saber é na realidade o que se chamada de complexidade no tempo do algoritmo, que é de n*log(n), onde n é o número de elementos O número de chamadas ao merge (que é o que é perguntado) não é a complexidade da função/algoritmo, visto que conta a chamada ao merge como 1, e não como a complexidade dessa função. O algoritmo começa por dividir as listas recursivamente em duas partes "iguais" até ter sub-listas de um elemento, e depois usa o merge para as voltar a juntar. Ou seja, para uma lista de N elementos usam-se N/2 chamadas à função merge para juntar N/2 pares de sub-listas de um elemento, obtendo-se N/2 sub-listas de dois elementos. Se agora temos N/2 sub-listas, temos (N/2)/2 pares de sub-listas, pelo usamos (N/2)/2 chamadas à função merge para voltar a juntar as sub-listas. Depois teríamos ((N/2)/2)/2 chamadas, etc. Isto repete-se até teres duas sub-listas de N/2 elementos, que precisam de uma última chamada para serem juntas. Assim, estaremos então a usar N/2 + (N/2)/2 + ((N/2)/2)/2 + ... + 2 + 1 chamadas à função merge. Sendo N = 2^n, ficamos com: 1 + 2 + ... + ((2^n)/2)/2 + (2^n)/2 = 1 + 2 + ... + 2^(n-2) + 2^(n-1) = 2^(n - 1) * 2 - 1 = 2^n - 1. 2 Report Rui Carlos Gonçalves
HappyHippyHippo Posted October 20, 2016 at 11:35 PM Report #599784 Posted October 20, 2016 at 11:35 PM 40 minutes ago, Rui Carlos said: O número de chamadas ao merge (que é o que é perguntado) não é a complexidade da função/algoritmo, visto que conta a chamada ao merge como 1, e não como a complexidade dessa função. está decidido, vou deixar de responder quando estou a dormir em pé ... a partir de agora, só de respondo de manhã 😄 IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now