Arbre binaire presque complet

On s'intéresse dans cet exercice aux arbres binaires presque complets. Un tel arbre binaire est soit :

  • un arbre vide ;

  • un arbre binaire dont tous les niveaux sont remplis à l'exception éventuelle du dernier qui, s'il n'est pas entièrement rempli, est « tassé » à gauche : tous les nœuds présents au dernier niveau se trouvent sur la gauche de l'arbre binaire.

Un arbre binaire presque complet

flowchart TD
    a((a)) --> b((b))
    a      --> c((c))
    b      --> d((d))
    b      --> e((e))
    c      --> f((f))
    c      ~~~ g(( ))
    style g fill:none,stroke:none,color:none
    classDef noeud font-family:consolas;
    class a,b,c,d,e,f noeud;

On n'a pas représenté les arbres binaires vides.

Cet arbre binaire est presque complet : les deux premiers niveaux sont entièrement remplis, les nœuds du dernier niveau se trouvent sur la gauche.

Un arbre binaire presque complet de taille \(n\) peut être représenté en machine par un tableau de \(n+1\) valeurs. En indexant les valeurs à partir de \(0\), on trouve :

  • une valeur quelconque à l'indice \(0\) ;
  • la valeur portée par la racine à l'indice \(1\).

Pour les autres nœuds, on considère les règles suivantes. Si la valeur d'un nœud est stockée à l'indice \(k\) :

  • si son sous-arbre gauche est non-vide, sa valeur est stockée à l'indice \(2k\) ;
  • si son sous-arbre droit est non-vide, sa valeur est stockée à l'indice \(2k+1\).

Avec Python, on peut donc représenter les arbres binaires presque complets à l'aide de listes. On place la valeur None à l'indice 0.

L'arbre vide est donc représenté par la liste [None].

Représentation de l'arbre binaire vu plus haut

L'arbre binaire dessiné plus haut a une taille de \(6\). Il est donc représenté par une liste de longueur 7 :

# indices   0   1    2    3    4    5    6
arbre = [None, 'a', 'b', 'c', 'd', 'e', 'f']

Le 'b' se trouve a l'indice 2. On trouve bien 'd' à l'indice 2*2 = 4 et 'e' à l'indice 2*2 + 1 = 5.

1. Taille de l'arbre binaire

Écrire la fonction taille qui prend en paramètre une liste représentant un arbre binaire presque complet et renvoie sa taille.

Exemples
>>> taille([None])
0
>>> taille([None, 'a', 'b', 'c', 'd', 'e', 'f'])
6

###(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

.128013.339tf}{)2rR3,sa-o! iug0xm1PpOnlh.e=céy:v^A(wq;S/b_dk050X0G0c0n0s0D0m0r0I0D0n0m0m0H010c0s0A010406050m0t0x0x0n0i0K040T0p0D0t0?0p0C0r020n0x0A0S0r0j0G100i0R0t0G0m050U0}0 11130{0A041r1y051B0U1B1D1y0{0X0s0M0+0-0/0;0E0s0u0E0D1R0E0c0_050$0V0D0G1M0.0:011Q1S1U1S0c1!1$1Y0c0V0p0X131Z0i1z0c0E0+160m0A0n0C0;0h011(1O010d0(0G0C1e0G1Y23252a1*2d1$2g0x2i040a0r0z0i0p0A0p0m0s191b0!210i0i0G0I2D1r2k0C1z0U1 2P0c1}1|1~0X2m0;1U0C2f2A1Y1J1L0,1)2Z0s2#0C1_1K1Y0A2I1z2N2P2`0|241b2+2b2:0i100D0_0y2M2~0`2}2l301*32340_0h38252P2@0G2P2)2S0X2W2Y010I1_2s0Z1K1z3m2_393j2O053v0!3C3c1N1*0Y0_0!0d3E3J2 3L0;0Q0_0r3R3b3T2,010C0d0_0$0(1$3Z2N3t0^040P3.2~3t0C0_110V2I3@3K3$3;0g0L3R060r473Y3/3d0;3N042I0c0t0i0C3R493^4b3%0V0_2p3 3#2b3;3?1s3D4a3U3%3{0i3}0G4s3:0_0g4k3!3t0p0_0o4K4z3$0x0s36451r3H3n1A2^1r3p1r0c3r4(2U2Q1^1`2S0n1#4Z0U3p1x3S3t2I0x0W0d0n0Y0G0W0E0k0_1j1l1n1p0r444x3k1A3a1y0B1b2:0c0G0i0n0r590l0r0X250*1$0+0.0r2@0J0I0s0*2F0I0#5l0r2I5A0m2f0$2D5s5a3|2I0*0V2.0%5T5z5T59211f1$0c0m5r1a5z0G185s1a0I0r0p0V5l0C0s0i0r0-0r3+0D5w2F0D005S1%2f0r2#0r4 5D250c5p0t000t6a0m0p0t0m2T0n2K0s5,0L3Y4Y3t1,1T1V1X4`4n0C4p044r5d3F4R4u0_4w2|6K3e4C4E4G4n424Q4m4A4N044P6I044l402b4T4V6$4X3w040F5f4_0O2.2B5}1%0I0n0D0I0t0D5Q5}5o60626i1b665$0A0$0C6f4L4n112C0E105l0w0_090P0y0v0N0f7q0e094J6$690b0t0X0*6k5m5o240*0A170*3v5%0s1n0J690s5}1a0u6g6{0G177S0X770r790M0s2F0q6=4$0#0%0)04.
2. Hauteur de l'arbre binaire

Écrire la fonction hauteur qui prend en paramètre une liste représentant un arbre binaire presque complet et renvoie sa hauteur.

Une version valide de la fonction taille est disponible dans l'éditeur ci-dessous. Vous pouvez directement l'utiliser sans l'importer.

Exemples
>>> hauteur([None])
0
>>> hauteur([None, 'a', 'b', 'c', 'd', 'e', 'f'])
3

###(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

.128013.33954)2R,a-! ièà8m16l7.e:9A;S/dktf+rj3sogu0xPpO*n`h=cLéyvD(wq_b050D0w0F0i0m0t0L0l0Z0t0i0L0L0Y010F0m0S010406050L0O0q0q0i0I0$040B0M0t0O110M0V0l020i0q0S0A0l0g0w1b0I0+0O0w0L050C181a1c1e160S041C1J051M0C1M1O1J160D0m0%0_0{0}0 0X0m0N0X0t1$0X0F14050;0-0t0w1X0|0~011#1%1)1%0F1/1;1-0F0-0M0D1e1.0I1K0F0X0_1h0L0S0i0V0 0f011?1Z010G0?0w0V1p0w1-2e2g2l1^2o1;2r0q2t040a0l0R0I0M0S0M0L0m1k1m0/2c0I0I0w0Z2O1C2v0V1K0C2a2!0F2827290D2x0 1)0V2q2L1-1U1W0`1@2.0m2:0V241V1-0S2T1K2Y2!35172f1m2_2m2~0I1b0t140r2X3915382w3b1^3d3f140f3j2g3l2Y2-013q0i3g040K3u2Z163x3o0 3A3C0d3F3w393y3L140c3O3H3Q3J3z0M3e3B140s3V3m3a1Y3p3!3r040u3)3I3,3K3.3$040p3=3X3@3Z3#3C0y3O1L331C2@2%0D2+3y0Z242D0.1V1K320w343k444d0/4l3n3 0E140/0G443?2`010*140l4x3~4z0V0G140X0i1j0w0O0I4E4r4z13040)4Q3+4G141c0-2T4W3y4T0e0x3V0l4-4D4y2m4t040m4w1D3k4/4F3c0-142A4%3Y4T4V4_3v3*3R4Z0I4#0w513 4)3O4{4R2m0M140Y0Y5g573Y0q0m3h5d4S144+553G4.5A5h4X4;142T0F4O0V5o4:1^5r140P4,4.5p3 0V140m5K4|1^5k045n5y045C3R4~04505%5S5v4U5u3c595b5=1^5f5%5)3Y5!0j5X5i5M5s043i5%065A5/5?040F615D5Z5l6e3y5N655Q4-6a1^4=0*1#1;6i3Y5U4?6u3 5!0k5$355}3 6k66375L0 4T5x35685B6n6J3z5V6y4z5!6C4`6o3K6T5|6Z015!0C0C6U2m6k3t676P6Q5Y6!6c6,6g5#6_6@6d6$6R5!0H6|016G6m6E4z4=5G5I736w6~6N1C4o4k457i0C481C0F4a7n2)2#23252%0i1:7k481I4q6f0 2T0q0,0G0i0E0w0,0X0K141u1w1y1A0l6M4m1P3l1J0!000m0D0#1=1A0F0l2Q2f0I110I7+0O0l0V0b0O2,1;0l0S1i0^0o7+2I2N1=0D7=0/0I0V0m0w7:890%0w4L0l0)7@7_7+7!0V1U0Z1=057h3y1`1(1*1,7B586x6 6?6(6h8B623K5+5-6I8C535_6@4!4$5.6R5{6D6%5 73755.0C7h040e0l0:7+1=7E1l0F8b0l800{0l0I0i0Z2|0w0v2G0M4O0_1=7H0m2T0l1l7+1V0m0L1=8p7*2|8o1=7-8*0O0Q0l0J0O0L1y00800i1~0w9e940t8m9f8*0l8=8@8_2:0v1L7X040T1m2K4O8@2N0l4L0}0m0h8:9B8m8e0I9a9U7-7/9A9C8^8`8h8;9y0m8p4D8s3Y8u1|1+2u8C8Y378!4e8$8(7*0/0L8p8n942Q0L8~0L0j8P1=0N4L0Z0X7(1ma99nac5a94af0Oah8{0l0(2g0^9:0Z0|951m4L9O7*5x1S4g2^3 9@8w9`8G2n2p2B2D2F0B0Z0I127*0R0$2a1l444j7B364m8#6%4=4v8N4A4Ca:4H4J4L8.4Oa:8M8R8C6wada|144*766%7d736W7c140;0?6ta~aOa}8KaOb0ao5cbf7C018T3k6O6=bj4Jb88E8U6R6k5P6:5R6R6w5W8Fbob9bH6j646Hbr696R6q6sbmbya 6#bUaO5!020t0F0A6X3v776b7e4m8S5w76bPbV8AbXbIbx6Ybz646/b@3y5!0Ubab?bO6;b6bvbK5~b_b)c6040Xbw0472c86FbMb5bQ5F0:7bci4Ycd3)9~4p7j2!7z1N040!7S2@990m1l0^180Z8p9S8e0^9h8r4e8t1*9^8x6%6.44cu4k0l0#0%0M7R0V7*1;ax1l9Y2McG8(1m0-2|0=2T8|0z2|2M9U2MaB2c0V2M0D0na77Sad0^2~0V0j0%7#1A9U8=4K4M8 0D000OaCbl0lc?2r939g2T9o1z2c1q1;7*7)9B0m7%9Q7=2~0q5b9Ac?0FcN8b2C1~2ga2000#aVdt9B0i0lbc0t7{2Q8p1i0m0j8_9G7W7AcB0^2(0M990l0G1l2VcFd20l181VdS7Sa9c)7+d{dG9S0l0%3Bde0^aG3l0O0t3l1)9I2q0l1j0?99dS9;cQ9?cSaM8y6v5+drcXa,d/aIcR1{ew6%2z2q2s14aTdW0SaYa!0Xa$5.a(3*a*56a,cm04a/bn3y4B5(a?4Icda_4N4Pe%521454bibobk5^e;5eb37U3vbsb*3pbbcfb(2Zf26}0=d$bTb-8Le?a?5@8Qe^4(b3cl8C4=4@c2b,cb705lf6e*b{5Ob204e 5zc5e!7a888X64bB6Nb;aO79cofGcq4}4 2qfze@fdbjez2|fUfg6^e|5:0e0ecf60fQ633s5gf8010Z0r1403dq2|0)0F8%dC320#2o0Q0#7|1c0l0W0P0-0We60V0Zd0al0L2(0=7*b}br7g9 cw474h160Cek16guczemeo1)0LercPd(aKev1}aNe_4 0M0Ngl56cY5(ef1T1VeF8vgHex3 eJaReM0laUaWeP2GeReT37eV9}37eZfn6w0G2I0qa:e)4Df%3c6w1b2ag`a=g}6pbF1q3!frf7cc0tgLgN3G3WfM4u0w4^fj3Yg{e+a^dje:hle}5;h48Oblfzb4bCbtgJf$b~c96{f-f9bdfc56b.huhscrb1hvbpflhAf;fohkb`b=h9fw8C6Wfvf;bAfzfB156;hVcn5HfPhEcjfyhUa-h:cph?4G5+2|h!6%bhfWhChcgMf!hRb7hR4)f*hH8DcgfH5t67gncv1P467lgr1Cgwgw1J7}9n95aW0Nc@0t9U0i8egegD9bgFeGgWb6h c)a:5!d.hO6bdM0,2A0Nh1ibe?id9}8#0l1y0m8?2qc$8a9B1=dIdK2QdM0^dldnc;118/gReEeuiI9_gX4zgZeL2Eg$eOeQa#5JeU46g/a+goe!e$iQ1^hni9e,dia`hri4fkhNjq6vfhhK2Zi2e~fmbuhDhYbYcahabEbbfabeji6Kffi9jvhyjAbohWfqf5h(cVfIh+b:bDfnh{h=jDboh*h_fEfOjah}b+iN14iPjt5T14iSiUiWjLhS4UiZgmgPgpio0%3lgt0mk7ehk70/d#0L04.