Wikipedia stipule que le temps d'exécution moyen d'algorithme QuickSelect ( link ) est O (n). Cependant, je ne pouvais pas bien comprendre comment cela est le cas. Quelqu'un pourrait-il m'expliquer (par rapport à la récurrence + utilisation de la méthode principale) sur la manière dont le temps d'exécution moyen est O (n)?
Parce que
nous savons déjà quelle partition notre élément désiré réside dans.
Nous n'avons pas besoin de trier (en faisant une partition sur) tous les éléments, mais uniquement de fonctionnement sur la partition dont nous avons besoin.
Comme dans le tri rapide, nous devons faire une partition dans des moitiés *, puis dans les moitiés de la moitié, mais cette fois, nous n'avons besoin que de la prochaine partition ronde dans un célibataire partition (moitié ) des deux où l'élément devrait se trouver.
C'est comme (pas très précis)
n + 1/2 N + 1/4 N + 1/8 N + ..... <2 N
Donc c'est o (n).
La moitié est utilisée pour plus de commodité, la partition réelle n'est pas exacte de 50%.
Faire une analyse moyenne des cas de QuickSelect One doit examiner la probabilité que deux éléments sont comparés pendant l'algorithme pour chaque paire d'éléments et en supposant un Pivotement aléatoire . De cela, nous pouvons tirer le nombre moyen de comparaisons. Malheureusement, l'analyse que je montrerai nécessite des calculs plus longs, mais c'est une analyse de cas moyenne propre, par opposition aux réponses actuelles.
Supposons le champ que nous voulons sélectionner le k
- ème élément le plus petit d'une permutation aléatoire de [1,...,n]
. Les éléments de pivot que nous avons choisis au cours de l'algorithme peuvent également être considérés comme une permutation aléatoire donnée. Au cours de l'algorithme, nous choisissons toujours toujours le prochain pivot réalisable de cette permutation par conséquent, ils sont choisis uniformes au hasard, car chaque élément a la même probabilité de se produire comme élément réalisable suivant de la permutation aléatoire.
Il y a une simple, mais très importante, d'observation: nous comparons seulement deux éléments i
et j
(avec i<j
) Si et seulement si l'un d'entre eux est choisi comme premier pivot élément de la plage [min(k,i), max(k,j)]
. Si un autre élément de cette plage est choisi d'abord, ils ne seront jamais comparés car nous continuons à rechercher dans un sous-champ où au moins un des éléments i,j
N'est pas contenu dans.
En raison de l'observation ci-dessus et du fait que les pivots sont choisis uniformes au hasard la probabilité d'une comparaison entre i
et j
est:
2/(max(k,j) - min(k,i) + 1)
(Deux événements sur max(k,j) - min(k,i) + 1
Possibilités.)
Nous avons divisé l'analyse en trois parties:
max(k,j) = k
, donc i < j <= k
min(k,i) = k
, donc k <= i < j
min(k,i) = i
et max(k,j) = j
, donc i < k < j
Dans le troisième cas, les signes moins égaux sont omis parce que nous considérons déjà ces cas dans les deux premiers cas.
Maintenant, prenons les mains un peu sale sur des calculs. Nous résumons simplement toutes les probabilités que cela donne le nombre de comparaisons prévu.
Semblable au cas 1, cela reste comme un exercice. ;)
Nous utilisons H_r
Pour le numéro harmonique R-TH qui pousse approximativement comme ln(r)
.
Les trois cas ont besoin d'un nombre linéaire de comparaisons attendues. Cela montre que QuickSelect a en effet une exécution attendue dans O(n)
. Notez que, comme déjà mentionné - le pire des cas est dans O(n^2)
.
Remarque: l'idée de cette preuve n'est pas la mienne. Je pense que c'est à peu près l'analyse de cas moyenne standard de QuickSelect.
S'il y a des erreurs, merci de me le faire savoir.
Dans QuickSelect, comme spécifié, nous appliquons la récursivité sur une seule moitié de la partition.
[.____] analyse moyenne des cas :
Première étape :t (n cn + t (n/2)) ==
où, CN = temps pour effectuer une partition, où c est une constante (peu importe).
[.____] T (n/2) = appliquer une récursion sur une moitié de la partition.
[.____] Comme c'est une affaire moyenne, nous supposons que la partition était la médiane.
Comme nous continuons à faire des récursions, nous obtenons l'ensemble d'équation suivant:
T (n/2 CN/2 + T (N/4)
[.____] T (n/4) = CN/2 + T (N/8)
.
.
.
[.____] T (2) = C.2 + T (1)
[.____] T (1) = c.1 + ...
) ==
Somme que les équations et l'annulation croisée des valeurs similaires produisent un résultat linéaire.
C (N + N/2 + N/4 + ... + 2 + 1 C (2n)) == // Somme d'un GP
Par conséquent, c'est O (n)