Votre formule est correcte, et les deux cas vous donneront une complexité O(nlogn).
première preuve :
Si vous écrivez l'arbre de récursion pour le premier cas, vous verrez qu'à partir de chaque nœud, vous vous brancherez sur un nœud qui est 1/10
la taille du problème actuel et à l'autre nœud qui est égal à 9/10
de la taille du problème actuel.
il est intuitif que la branche gauche atteindra le cas de base en premier (puisque nous utilisons une plus petite partie du problème dans cette branche) et donc la plus grande complexité sera dans la branche droite.
à chaque fois que vous allez à droite, vous résolvez un plus petit problème qui est 9/10
la taille du problème situé au-dessus de lui (son parent). La question qui se pose est donc de savoir quelle est la profondeur d'un tel arbre (combien de fois puis-je diviser mon problème par un facteur de 10/9
)
il n'est pas difficile de voir que la réponse est :
log(10/9) N
à chaque niveau de l'arbre, nous devons passer par N valeurs (ce qui représente l'ensemble du tableau ou du vecteur), la complexité temporelle est donc de :
N * log(10/9) N = N * (log(2) N / log(10/9)
mais log(10/9)
est juste une petite constante, donc la complexité temporelle est :
N * log(2) N
seconde preuve
c'est très similaire à l'autre, dans ce cas la profondeur de l'arbre de récursion sera deux fois plus grande que dans le cas du quicksort parfait (qui est celui où nous obtenons toujours la valeur du milieu comme pivot)
Pour comprendre cela, imaginez simplement que la moitié du temps nous allons atteindre la condition paire, ce qui nous fera diviser le tableau parfaitement ; si une telle condition se produit la moitié du temps, cela signifie que nous diviserons le tableau 2 fois plus que nous ne le ferions dans un monde parfait (le pivot divisera toujours le tableau en deux).
2 * N * log(2) N = N * (log(2) N
référence : https://www.khanacademy.org/computing/computer-science/algorithms/quick-sort/a/analysis-of-quicksort