Partition autour d'un pivot

On se donne un tableau nombres non-vide ne contenant que des nombres entiers.

On souhaite réaliser une partition de ce tableau autour d'une certaine valeur appelée « pivot ». Une fois ce « tri » effectué, le tableau comportera dans l'ordre :

  • toutes les valeurs strictement inférieures au pivot,
  • toutes les valeurs égales au pivot,
  • toutes les valeurs strictement supérieures au pivot.

Il s'agit d'une partition et non d'un tri, car la première et la dernière zone ne sont pas nécessairement triées.

Par exemple, la partition de [3, 0, 2, 1, 5, 1] autour de la valeur pivot 1 donnera [0, 1, 1, 5, 2, 3].

Pour ce faire, on crée et l'on maintient quatre zones dans le tableau :

  • la première zone ne contient que des valeurs strictement inférieures au pivot (en bleu ci-dessous),

  • la deuxième que des valeurs égales au pivot,

  • la troisième contient les valeurs mal placées (en gris),
  • la dernière zone ne contient que des valeurs strictement supérieures au pivot (en rouge).

Étape intermédiaire

Ces zones sont délimitées par les bornes suivantes (incluses) :

  • Valeurs strictement inférieures au pivot : de l'indice 0 à debut - 1,
  • Valeurs égales au pivot : de debut à milieu - 1,
  • Valeurs mal placées : de milieu à fin,
  • Valeurs strictement supérieures au pivot : de fin + 1 à len(nombres) - 1

Au fil de l'algorithme, la zone contenant les valeurs mal placées rétrécit. L'algorithme se termine lorsqu'elle est vide.

L'algorithme à coder est donc le suivant

  • on crée une variable debut égale à 0,
  • on crée une variable milieu égale à 0,
  • on crée une variable fin égale au dernier indice de nombres,
  • on répète les étapes ci-dessous tant que milieu est inférieur ou égal à fin :
    • si la valeur d'indice milieu est strictement inférieure au pivot, on l'échange avec celle d'indice debut et l'on incrémente debut et milieu,
    • si elle est égale au pivot, on incrémente milieu,
    • sinon, elle est strictement supérieure au pivot : on l'échange avec celle d'indice fin et l'on décrémente fin.

Étape 0

Dans l'état initial aucun nombre n'a été trié.

  • debut = 0
  • milieu = 0
  • fin = 5

Étape 1

On a échangé les valeurs d'indices 0 et 5. fin a été décrémenté.

  • debut = 0
  • milieu = 0
  • fin = 4

Étape 2

On a échangé les valeurs d'indices 0 et 1. milieu a été incrémenté.

  • debut = 0
  • milieu = 1
  • fin = 4

Étape 3

On a échangé les valeurs d'indices 1 et 0. debut et milieu ont été incrémentés.

  • debut = 1
  • milieu = 2
  • fin = 4

Étape 4

On a échangé les valeurs d'indices 2 et 4. fin a été décrémenté.

  • debut = 1
  • milieu = 2
  • fin = 3

Étape 5

On a échangé les valeurs d'indices 2 et 3. fin a été décrémenté.

  • debut = 1
  • milieu = 2
  • fin = 2

Étape 6

On a échangé les valeurs d'indices 2 et 2. milieu a été incrémenté.

  • debut = 1
  • milieu = 3
  • fin = 2

milieu est désormais strictement supérieur à fin. On sort de la boucle.

Échange de valeurs

Il est possible d'échanger deux valeurs d'indices i et j en faisant nombres[i], nombres[j] = nombres[j], nombres[i].

Fonctions, opérateurs ou modules interdits

Dans cet exercice on interdit d'utiliser :

  • sorted

  • list.sort

Exemples

🐍 Console Python
>>> # Le pivot est 1
>>> nombres = [3, 0, 2, 1, 5, 1]
>>> tri_pivot(nombres, 1)
>>> nombres
[0, 1, 1, 5, 2, 3]

Les trois zones sont [0], [1, 1] et [5, 2, 3].

🐍 Console Python
>>> # Le pivot est 7
>>> nombres = [7, 2, 5, 5, 9, 1, 9, 7, 2, 5]
>>> tri_pivot(nombres, 7)
>>> nombres
[2, 5, 5, 5, 1, 2, 7, 7, 9, 9]

Les trois zones sont [2, 5, 5, 5, 1, 2], [7, 7] et [9, 9].

Écrire la procédure partition qui prend en paramètres un tableau de nombres entiers et un entier représentant la valeur du pivot, et qui modifie en place le tableau.

Rappel : procédure

Une procédure est une fonction qui ne renvoie rien.

En python, même si une fonction ne contient pas le mot-clé return, elle renverra toujours par défaut l'objet None.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10
.1280135[4)2R,%a- ièà8m16Cl7.e:9AH;S/dktfù+«rjT3sogu0x]PpOnE»h=céLyvDê(wq_b050F0x0H0j0m0u0Q0l0)0u0j0Q0Q0(010H0m0Y010406050Q0T0q0q0j0M0,040D0R0u0T180R0!0l020j0q0Y0C0l0g0x1i0M0=0T0x0Q050E1f1h1j1l1d0Y041J1Q051T0E1T1V1Q1d0F0m0-101214160%0m0S0%0u1-0%0H1b050{0@0u0x1(1315011,1.1:1.0H1_1{1@0H0@0R0F1l1^0M1R0H0%101o0Q0Y0j0!160f011}1*010I0}0x0!1w0x1@2l2n2s1 2v1{2y0q2A040a0l0X0M0R0Y0R0Q0m1r1t0_2j0M0M0x0)2V1J2C0!1R0E2h2+0H2f2e2g0F2E161:0!2x2S1@1#1%111~2^0m2`0!2b1$1@0Y2!1R2)2+3c1e2m1t302t350M1i0u1b0l0r2(3g1c3f2D3i1 3k3m3o0f3r2n3t2)2@013y0j3n040l0P3C2*1d3F3w163I3K0l0d3O3E3g3G3U3o0b3Y3Q3!3S3H0R3l3J3o0s3)3u3h1)3x3.3z3L0v3?3R3_3T3{3:3L0p3 3+413-3/3V0z473v493$040r0U4e3^314a3|0r3q1K3s3*4f4n4h0r3B4s3D4u4m3j433K0r3N4A3P3@3#4F1b0r3X4J3Z4v4E4b4O3(4R1S3a1J2~2.0F2=3G0)2b2K0^1$1R390x3b3s3Y054+0_4?4T1 0G1b0_0I4^404n0;3o53484w0I1b2m0M182%4Y542t1a040:584}3T1b350q0@2!1I5h595j1b0h3Y0l4L3,0!5c1$0R0H5n4D1 5k0e0y3)0l5R5C5i3x500x0@1q5B5D490R1b0(5!5U160q0m1b4k4R065S5T5x5V045-1:0x0T5*5^165%045)4R5@5o015-5/5Q5S5#4w1b2v0!5 6762643c665L3T0@1b2H5K3G5k5m5w675F045r5t1H6t3,5N6i6o01620k6H3G694i3)5=6c5+014 040;1,1{6M5E1b5{0m5}6!5$1b020u0H0C6l3s6n3#6f336E495k5P5;5?5?6d2t6V0m5265715_6B5u6`4n5k0c7b3j6$0}6(5~6x6I5k0W6*4n626-6/7p7g040Y5H5J7l6u1b6}3c6R6 6 775p6A0R5s7a7A6F1b7e7O4g7h5|7k3e6T7n5A766T6z796D7S7c7Q7f5_0_5Y7z7X60017n7u1 6k7_7J7(5v7=677d7-7J7/5Z7*5y040W7!6m7I3H5q7L6C7 4@7Y7,875_6%6)8m167^6~7G7H7$5W7:7|6J1b0K6;3D6?3,6O4r7E8u8v7?6z8o7W6=8d628C8z8H6b7G8d6V0x1:758c8w7K7M7)807m8l8,6@5`7i8p8/7P898z6k8D2*8F7T7w7y837@7C8W8K8~6e8;7V8`8B8|3L8d8V8t8X6T8Z0~0x926|958K8d7%8g7N8@6{8.8j8M7U7j9n1b8a8z9s8*8i3D8d828q8e046g9C8_7#7?7{9S6y8f9H9Q7R9v989P9M7Z9F9X8h9Z928N8=8P9J8k9R8J965R9r6^6h9V6I6K9d972t9g7E1J4`4=4Za80E4$1J0H4(ad2:2,2a2c2.0j1`aa4$1P4|6I2!0q0?0I0j0G0x0?0%0P1b1B1D1F1H0l7D4@1W3t1Q0.2n0 1{10130l0R0J0laR260x0j0T0l2`2j1x3.0H1|aG0l2/0R0m0 0-3J5}0M0 1#0Q180!2$1H0haU1t2!a:0T0-1|aR390R1`0n2J0l1#0Hbga$050j0l0%2!0I1+250Y0Q0y0E0E0I0M0w0;0m0G190x1#0j0w3.0S0EbBbD0E2Obc0u0i0t0P0i0A0p2J0?0F0TbZ0M0j0Ya!b#0%1o120!0F0|0Q1@1C040.b%b)a#0l0Bb-2nb:a=1Jb@1J0j3L33b80!0H0*0l5d0l0#0w0l0.0m0N0Ga}b%b2a.0u001s0lb52Pb7ccb:0!0 0)0`0l0x0V0x0M0)0mcCaI5Cbmbo0xbq010w0w0EcT0EcFcHcJcC0Q2,0M0m0?a:a=0?a@1{0Ta`0E1b0Oc(a/2Pa=0lc.a_5vc61SaM040+000jb:0Y0{2V0l0o0l0T1t7(0laG0u4+0!a.2Xc}c:0 390*0Q2xcb1|cK0mcd5}0H0k0/2/1|1q7i0Q0*1|czaQ1|0)d62!bj0l0LcNbnbp16cWcW2xc*b%a@0T0Vc%c)b`0m0_c=042/dyd,0_c53L0$chaOcA10cD3J0S3.2U0%2Jb2ctd;1|0M0*0)dp1$1CduaXaHdoa`0la#0H0Rc:bg00de1|ejcd7ya)bfdLaX00cYcIcK0x0wd1aq0Z1tb)1qa/eoa,0Ia;0 0q1sdE0Mdh1GaX3.0Qcq1|aZb|dce8eW4+a*5e1|eLbgeta^dpbga=a~b00 0:2!1218b82Jcadb0l0Qbm0{0}1{0eb2120l0q0*2h4,cd2P2RdIdwcJcEa}cd1p0 33cb5uf7caa-eYfefgfi2X3w0maGchd40ja@ca0j0Sfody1Hbi2xcE0I0IcD0Fcs0M0S2na=cHeha/am1{b|emeoeWb!ev0-5Iffb;el0T14dy1ea:0!0S042X2!0Scwb)eW1{a?e@ek0*f$gaf{f?5I2(g0g2ghcCcadQf=e(0TeGaL1dab0`0|0~04.