Arbre binaire additif

On souhaite construire des arbres binaires parfaits « additifs ». Dans ces arbres :

  • tous les niveaux sont entièrement remplis ;
  • la valeur d'un nœud intérieur est toujours égale à la somme des valeurs de ses enfants.
Un exemple d'arbre binaire additif

graph TD
    R(19) --> A(8)
    R --> B(11)
    A --> C(3)
    A --> D(5)
    B --> E(7)
    B --> F(4)
    C -.-x G( )
    C -.-x H( )
    D -.-x I( )
    D -.-x J( )
    E -.-x K( )
    E -.-x L( )
    F -.-x M( )
    F -.-x N( )
    style G display:none;
    style H display:none;
    style I display:none;
    style J display:none;
    style K display:none;
    style L display:none;
    style M display:none;
    style N display:none;

Cet arbre est :

  • parfait (tous ses niveaux sont remplis) ;

  • additif (on a \(3 + 5 = 8\) ; \(7 + 4 = 11\) ; \(8 + 11 = 19\)).

On demande d'écrire la fonction arbre_additif qui prend en argument la liste valeurs contenant les valeurs des feuilles et renvoie l'arbre correspondant représenté à l'aide de tuples.

On garantit que le nombre d'éléments de valeurs est une puissance de \(2\) strictement positive. Ces éléments sont tous des nombres entiers.

Représentation des arbres en machine

On représente les arbres binaires ainsi :

  • l'arbre vide est représenté par None,

  • un arbre non vide est représenté par un tuple (sous-arbre gauche, valeur, sous-arbre droit).

Ainsi le tuple ((None, 6, None), 15, None) représente l'arbre suivant :

graph TD
    R(15) --> A(6)
    R -.-x B( )
    A -.-x C( )
    A -.-x D( )
    style B display:none;
    style C display:none;
    style D display:none;

Exemples
>>> arbre_additif([6])
(None, 6, None)
>>> arbre_additif([6, 9])
((None, 6, None), 15, (None, 9, None))
>>> arbre_additif([3, 5, 7, 4])
(((None, 3, None), 8, (None, 5, None)), 19, ((None, 7, None), 11, (None, 4, None)))
Parcours possible

L'algorithme peut être construit autour d'un parcours en largeur partant du dernier niveau de l'arbre (les feuilles) et remontant, niveau par niveau, jusqu'à la racine.

Avec deux list...

On peut, par exemple, débuter en construisant une liste contenant les feuilles. On calcule ensuite la liste contenant les nœuds du niveau supérieur.

Ce calcul effectué, on remplace la liste des nœuds par la nouvelle et on répète la démarche jusqu'à atteindre la racine.

... ou avec une file

On pourra aussi utiliser une structure de file afin de mettre œuvre un parcours en largeur « remontant » l'arbre.

On fournit à ce titre les fonctions creer_file, enfiler et defiler d'ores et déjà chargées en mémoire et utilisables sans effectuer d'imports.

🐍 Console Python
>>> f = creer_file()  # création d'une file vide
>>> enfiler(f, 0)     # on enfile la valeur 0 dans f
>>> enfiler(f, 1)     # on enfile la valeur 1 dans f
>>> enfiler(f, 2)     # on enfile la valeur 2 dans f
>>> defiler(f)        # on défile, et l'on récupère, une valeur de f
0
>>> defiler(f)        # on défile, et l'on récupère, une valeur de f
1
>>> defiler(f)        # on défile, et l'on récupère, une valeur de f
2
>>> len(f)            # nombre d'éléments dans f
0
###(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.33942znygN )TrPq-;oàèu5(,:éts]h07w+8f/63pOv1Àx=a_ckmLieS9l[Rb.d050-0#0A0U0!0(0B0j0W0(0U0B0B0T010A0!0N010406050B0u0Y0Y0U0m0g040$0r0(0u110r0f0j020U0Y0N0q0j0*0#1b0m0o0u0#0B050K181a1c1e160N041C1J051M0K1M1O1J160-0!0P0_0{0}0 0D0!0h0D0(1$0D0A14050;0+0(0#1X0|0~011#1%1)1%0A1/1;1-0A0+0r0-1e1.0m1K0A0D0_1h0B0N0U0f0 0d011?1Z010J0?0#0f1p0#1-2e2g2l1^2o1;2r0Y2t040a0j0n0m0r0N0r0B0!1k1m0/2c0m0m0#0W2O1C2v0f1K0K2a2!0A2827290-2x0 1)0f2q2L1-1U1W0`1@2.0!2:0f241V1-0N2T1K2Y2!35172f1m2_2m2~0m1b0(140j0Q2X3915382w3b1^3d3f3h0d3k2g3m2Y2-013r0U3g040j0M3v2Z163y3p0 3B3D0j0c3H3x393z3N3h0v3R3J3T3L3A0r3e3C3h0L3Y3n3a1Y3q3%3s3E0F3,3K3/3M3;3)3E0I3^3!3`3$3(3O0%403o423V040Q0E473.2`433=0Q3j1D3l3Z484g4a0Q3u4l3w4n4f3c3|3D0Q3G4t2Z1L331C2@2%0-2+3z0W242D0.1V1K320#343l3R054M0/4U4o2m0X140/0J4W3_4g0G3h4+414p0J141c0+2T0V0U0-1U114*4C4!4w1^13040w4:4#3q140P3C0#0u0m1B513-3z550k0y3Y0j5p0j5j3#0f142z0#3R5r4,2m0r140T5y5s49140W2T0#0m0V5w58530 550w0k5o5q5G4g4%040J3%5F5A5a040S5%4;5B4.042|5,593M5b5d5f5h375(5R145n51065q635z5-5)2~5e0-5=5Q015C045E51655?015S5P3z0X0W140i1l5x5i5}6k140x6b3U145+6u665~046y6h5X4$6p046r2:6m3#5l5V646i6c5u042q5w0m6P426l6D6j6W5O6(6c556H356U6A04680u6a6,5k145U61625W6v5Z0G1#1;6z5t0+142A6#4g6%5|6E3A5v2p7b2m6R6I6v6e020h0A0q76420Y0!144k7e6j5560356 6T6J5)0h0U0u0W0D6t6:7G0 6e6g7O6v6W4)2p6!6`6Q14577Z5H5!7i7%7c6|6S647P7g040-2I2N7N3l6;3#7R7t4p4(0#6Z7j547#835@7)757+7k7-616T5p7:6W0B0r1a7_3w7{427}7m7f6W7I7K7M866w040)8w7v7x8w550C7~5B140H8G5)7?0r7^8D148z8a1^8B4b8P048F8d8e8g146Y7X8W7$7z6V7h898+6{6G8K6F8*4V7U148t7L8l4D6v6.8=7;8i8k8W6/7`8#7=7@0A8}528:0k6}7D7E8n5Y142T0A5f0f917V818(8S8?8w6*7*8/7!049g4m1C4Y4T4E9G0K4H1C0A4J9L2)2#23252%0U1:9I4H1I9d3#2T0Y5N0U0X0#0V0D0M141u1w1y1A0j7C4V1P3m1J0Z000U0N320r8|0j0U0P2U0j0/0u0S0j1)0B9b0^1A0Aab0U0j181V2g9b9?1L3m2@3z1`1(1*1,9Z425w2B2D2F0$5J12ah0n0g2a1l4W4S52364V9Fay9k7=818w5/5r9u3A4?044^4`4|4~0!509z6$85aZ6W5c1;5`8W5m7.980f1V0#7J918p7T7f550)8@3w7:6o6q6s959q6Bbc8q6jb96MbbaZ7lb2bh5v5$bg8,5*b05/5;br6=a=5e5g8W8Y9h63b814739y977U78047abla/a-7 6?a}a bP9Bb0147p7r918U7y8^b35 7.bF8_aU0}0u5{bK7fb1b?7A8QbD4m8e9j4$bp7Ybnbs0!bu14bwc33UbM0m2g0h9c7:7db)6j8U4dbW968m8gbMbObR8b569w14a|a5bVcs849Bcn2Zb 8T7w044scA6Fa_8Zb~8fb.8{8vbx7|5DbdbTcy0u8W8RcK7;c5bWb|4ucO708r4(9abY6fcWcxa~cZbWc#cic4c;8JcT7ucHb(b78 14c*3Ic,cPc.04932Cc;7Sb_bscRcfd58y8Ad2bCc~cW8M2Nc!dn8Cc)b,8!b.0/b:b=d4b@140,cva$9 2q6_c$5Sb68~dbdjbfc95t14dddkb*8;d0bSds0Aa^9Cc+dzdbc@czdh3zb^codA1A18dD3I9ibG049m9oc?bUc_dN8Qdv04cle48X3,0KaR9H2!9X1N049|9~a0a20m0z0W5`a}0jag0j0N1i0^180+111;0,0j0O1m0N5eah0-0z0+1j5Les1meo0mam0fah601S4P2^42au1|1+2u7faA2s14aDaF0NaHaJ0DaL5iaN3-aPb7ed7180a,c|3zaX9wa#a%9*a)2Na+8)dIbza@bWcM7Db-d-df9qcq2qf9a:5^a?bBfd3Yd|e|5:e~d?fhd#8H6fdgfxcjdobW9@8m9ifgbod~0:e0fzcBdPaS6Kba6OcmcWfbfqe9c{dEfE14e8e 9A0CcD3Eb86L6NdYb`bX6~fK6c5Zd 0m9pfP9vfna$0m4_f54}f7fwdQf?fR98fYd`fScB0)fHg9bsf~c$6e0K0Ke6cJf*a.8X0kf-cF3MbM1Efmc$a;5_fZgs7,cCcWf44{g64 gBgG3cfobAgecge5g1glgP1^gngpaZ8Ugrf$6-5 0C9febed1P4F9J4Q9Y0l0reM5#0!0B0x0_0:ao0Y0zaK2Qaja8aa2|4M0f0P0za|2q0A0^eV3m0u0(3m1)bN9=dXex1lah0W3Cep0(0z9=0seuew0!gS0j2T32g|9=7s0Khn16hn1l0_en1=2Q2~0Yg4b;9=4M0NhD0^2f0m110#0(1;0^2Q0{abg|ao4X4N04gd9Eh@0j1y0!0ja1epeGeT0j2|1j2p2Ci3h/h20Y8N2TdHhL0!3m0Khk9`04eEeueHeu3ChD0mg h-5eaaa01:0t2C0^hA0(9}0!2Qh.aja55g0!hP0W0!0pdB8ib;ap9_1T1Vat1*e#ax7:e)2Ce+0jaEeRe.2Ge:e=37e@375ie{7f5Z4)aW4/a:f3g3a(gMf8bWgbb.h_fWf 7;0/eLd(aZd=gj6nf:bke9gw982ogXg)d;cVaZbif;a^gi15f_6nc7g8f.d@jcc65:gegx01jtjjgY6FjwfJc-6)80jEj9jfjC7fckdydajR7)jocE7:jVjI0ffkj%gfg0gCgRfce9d*d{jy3#5Zj3dU7(jnc;0pdr0#jTj~4g7RfCj(6vb%8Wjwj!6c0W0Q14030j0u2:ak5e1;0jfYa72g0^h/0e6sa700h36^9cjPkfjzfM9nf}91chjpj{jifVjkfXgEgTdlf#jgdVaUk5jM8xf,91jKkPk!bm4mftdb7v1)5efij9kLkWj c8d:cU04c k6gQkY1ja^c;gob$cHg(d8jQdi7J8|k=k 5)gKf6gNj4fakSdTk{7(jbl2j8lf87k/hDe3k*8c6:jIkhkjh 1m2(a40=h+1=18itia8N110z0jdScNj+c/lO9cjIj*98lhj2jBgUcug1j7kQj96Wlvk;lslobSk0fr6hlBki04kkhPlG5c0?kqlLai0jicf7lQd%kDj`7(dXlel=l0lSf!e6d3k^gHd7jW6j6ek~mf8L9af=g*dmg$fFe9mnkF3#lCl|ak8j2C0j01812ohu0W2tfsmbaTf|j.jIk@j/7;mhlyd!lt92mHmv8:jldAmul361h`4Zee4Gg?eh0R0_0D0U9;0jh39~1=hP0f9}j21lknm}h,a7iwkrkSna0^0f0b6^0^2|0J0zeRhE0:lE0jkn5Jhyiqiv2ch!9=iIh:ad1=2qkleAg|annei40f1UmOh-0z2M0h2ri39;lJ0jkxkn4SnL2TeO2c1qao0-kum`m|1za3dK0(hFeoeq0JifeW9J0:lI0B04.