Une technique souvent efficace, lorsqu’elle est possible, consiste à diviser un problème en plusieurs sous-problèmes indépendants, puis à les résoudre récursivement.
I. Principe
Le paradigme de programmation « diviser pour régner » (ou divide and conquer) consiste à ramener la résolution d’un problème dépendant d’un entier n à la résolution de un ou plusieurs sous-problèmes indépendants dont la taille des entrées passe de n à n2 ou une fraction de n.
Les algorithmes ainsi conçus s’écrivent de manière naturelle de façon récursive. Le procédé « diviser pour régner » est un cas particulier de la récursivité, où la taille du problème est divisée à chaque appel récursif plutôt que seulement réduite d’une unité.
II. Exemple de l’exponentiation rapide
Le calcul de la puissance d’un nombre définie par a0=1 et an=a×an−1 n’est pas optimal. Il peut être amélioré de la manière suivante :
a0=1 ;
si n est pair, an=a×an/2 ;
sinon an=a×a×an−1/2.
La taille du problème est divisée par deux à chaque appel récursif. On a donc une relation de récurrence de la forme Tn+1≤Tn2 et T1=1 qui mène à Tn=Θlog2n.
III. Tri fusion
Le tri fusion permet de trier une liste lst selon le principe « diviser pour régner ».
Pour rassembler deux listes lst1 et lst2 déjà triées, on peut les interclasser de manière suivante : on compare les plus petits éléments de chacune d’elles, on place le plus petit des deux dans une nouvelle liste lstn et on poursuit cette opération jusqu’à épuisement de l’une des deux listes. On complète alors lstn en ajoutant à la fin de celle-ci les éléments de la liste non vide.
Le tri fusion est alors défini de la manière suivante :
si la liste lst a au plus un élément elle est déjà triée ;
si la liste lst a deux éléments ou plus, on partage lst en deux sous-listes de même taille, à un élément près, puis on appelle récursivement la fonction sur chacune des sous-listes et on interclasse les sous-listes triées.
Exemple illustré par un schéma :
Exemple de programme en Python :