Très probablement, cette question est posée avant. C'est du problème 6.5-8 de CLRS (2nd Ed) -
Donnez un algorithme de temps pour fusionner listes triées en une seule liste triée, où est le nombre total d'éléments dans toutes les listes d'entrée. (Astuce: utilisez un min-tas pour la fusion -way.)k n k
Comme il y a listes triées et un total de valeurs, supposons que chaque liste contient des nombres , de plus chacune des listes est triée dans un ordre strictement croissant et les résultats seront également stockés dans l'ordre croissant commande.n n
Mon pseudo-code ressemble à ceci -
list[k] ; k sorted lists
heap[k] ; an auxiliary array to hold the min-heap
result[n] ; array to store the sorted list
for i := 1 to k ; O(k)
do
heap[i] := GET-MIN(list[i]) ; pick the first element
; and keeps track of the current index - O(1)
done
BUILD-MIN-HEAP(heap) ; build the min-heap - O(k)
for i := 1 to n
do
array[i] := EXTRACT-MIN(heap) ; store the min - O(logk)
nextMin := GET-MIN(list[1]) ; get the next element from the list 1 - O(1)
; find the minimum value from the top of k lists - O(k)
for j := 2 to k
do
if GET-MIN(list[j]) < nextMin
nextMin := GET-MIN(list[j])
done
; insert the next minimum into the heap - O(logk)
MIN-HEAP-INSERT(heap, nextMin)
done
Ma complexité globale devient . Je n'ai pas pu trouver de moyen d'éviter la boucle à l'intérieur de la boucle pour trouver l'élément minimum suivant à partir de k listes. Y a-t-il un autre moyen de contourner? Comment obtenir un algorithme ?O ( k ) O ( n ) O ( n lg k )
4
, si vous choisissez une liste aléatoire, vous pouvez finir par insérer8
, ainsi le tas sera[7, 8, 10]
, à partir duquel vous insérerez7
plutôt que5
dans le jeu de résultats, ce qui sera faux.Tout d'abord, je pense que votre hypothèse de toutes les listes ayant entrées n'est pas valide si le temps d'exécution de l'algorithme dépend de la longueur de la liste la plus longue .n/k
Quant à votre problème, l'algorithme suivant devrait faire l'affaire:
Le temps d'exécution est évidemment dans et l'algorithme trie correctement r e s u l t .O(klgk+nlgk)=O(nlgk) result
Preuve (ou du moins, une idée de preuve). Considérez l'invariant de boucle suivant: Le -ème élément à insérer dans r e s u l t est toujours le minimum du min-tas H à l'étape i et donc, r e s u l t [ 1 .. i ] est correctement trié après la i- ème itération.i result H i result[1..i] i
la source