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
.339.128013s3_8èufvy n7aS1me(P24:twi][h)6Oo;bcdg/T0làqp.rL-,À=+Nzk95Rxé050L0s0y0o0A0Q0c0l0K0Q0o0c0c0!010y0A0T010406050c0h0r0r0o0V0k040p0H0Q0h110H0m0l020o0r0T0I0l0+0s1b0V0S0h0s0c050N181a1c1e160T041C1J051M0N1M1O1J160L0A0j0_0{0}0 0D0A0M0D0Q1$0D0y14050;0J0Q0s1X0|0~011#1%1)1%0y1/1;1-0y0J0H0L1e1.0V1K0y0D0_1h0c0T0o0m0 0v011?1Z010i0?0s0m1p0s1-2e2g2l1^2o1;2r0r2t040b0l0u0V0H0T0H0c0A1k1m0/2c0V0V0s0K2O1C2v0m1K0N2a2!0y2827290L2x0 1)0m2q2L1-1U1W0`1@2.0A2:0m241V1-0T2T1K2Y2!35172f1m2_2m2~0V1b0Q140l0q2X3915382w3b1^3d3f3h0v3k2g3m2Y2-013r0o3g040l0d3v2Z163y3p0 3B3D0l0w3H3x393z3N3h0*3R3J3T3L3A0H3e3C3h0F3Y3n3a1Y3q3%3s3E0n3,3K3/3M3;3)3E0f3^3!3`3$3(3O0)403o423V040q0P473.2`433=0q3j1D3l3Z484g4a0q3u4l3w4n4f3c3|3D0q3G4t2Z1L331C2@2%0L2+3z0K242D0.1V1K320s343l3R054M0/4U4o2m0(140/0i4W3_4g0z3h4+414p0i141c0J2T0e0o0L1U114*4C4!4w1^13040t4:4#3q140j3C0s0h0V1B513-3z550E0x3Y0l5p0l5j3#0m142z0s3R5r4,2m0H140!5y5s49140K2T0s0V0e5w58530 550t0E5o5q5G4g4%040i3%5F5A5a040,5%4;5B4.042|5,593M5b5d5f5h375(5R145n51065q635z5-5)2~5e0L5=5Q015C045E51655?015S5P3z0(0K140$1l5x5i5}6k140Y6b3U145+6u665~046y6h5X4$6p046r2:6m3#5l5V646i6c5u042q5w0V6P426l6D6j6W5O6(6c556H356U6A04680h6a6,5k145U61625W6v5Z0z1#1;6z5t0J142A6#4g6%5|6E3A5v2p7b2m6R6I6v6e020M0y0I76420r0A144k7e6j5560356 6T6J5)0M0o0h0K0D6t6:7G0 6e6g7O6v6W4)2p6!6`6Q14577Z5H5!7i7%7c6|6S647P7g040L2I2N7N3l6;3#7R7t4p4(0s6Z7j547#835@7)757+7k7-616T5p7:6W0c0H1a7_3w7{427}7m7f6W7I7K7M866w040C8w7v7x8w550B7~5B140#8G5)7?0H7^8D148z8a1^8B4b8P048F8d8e8g146Y7X8W7$7z6V7h898+6{6G8K6F8*4V7U148t7L8l4D6v6.8=7;8i8k8W6/7`8#7=7@0y8}528:0E6}7D7E8n5Y142T0y5f0m917V818(8S8?8w6*7*8/7!049g4m1C4Y4T4E9G0N4H1C0y4J9L2)2#23252%0o1:9I4H1I9d3#2T0r5N0o0(0s0e0D0d141u1w1y1A0l7C4V1P3m1J0W000o0T320H8|0l0o0j2U0l0/0h0,0l1)0c9b0^1A0yab0o0l181V2g9b9?1L3m2@3z1`1(1*1,9Z425w2B2D2F0p5J12ah0u0k2a1l4W4S52364V9Fay9k7=818w5/5r9u3A4?044^4`4|4~0A509z6$85aZ6W5c1;5`8W5m7.980m1V0s7J918p7T7f550C8@3w7:6o6q6s959q6Bbc8q6jb96MbbaZ7lb2bh5v5$bg8,5*b05/5;br6=a=5e5g8W8Y9h63b814739y977U78047abla/a-7 6?a}a bP9Bb0147p7r918U7y8^b35 7.bF8_aU0}0h5{bK7fb1b?7A8QbD4m8e9j4$bp7Ybnbs0Abu14bwc33UbM0V2g0M9c7:7db)6j8U4dbW968m8gbMbObR8b569w14a|a5bVcs849Bcn2Zb 8T7w044scA6Fa_8Zb~8fb.8{8vbx7|5DbdbTcy0h8W8RcK7;c5bWb|4ucO708r4(9abY6fcWcxa~cZbWc#cic4c;8JcT7ucHb(b78 14c*3Ic,cPc.04932Cc;7Sb_bscRcfd58y8Ad2bCc~cW8M2Nc!dn8Cc)b,8!b.0/b:b=d4b@140Ucva$9 2q6_c$5Sb68~dbdjbfc95t14dddkb*8;d0bSds0ya^9Cc+dzdbc@czdh3zb^codA1A18dD3I9ibG049m9oc?bUc_dN8Qdv04cle48X3,0NaR9H2!9X1N049|9~a0a20V0-0K5`a}0lag0l0T1i0^180J111;0U0l0G1m0T5eah0L0-0J1j5Les1meo0Vam0mah601S4P2^42au1|1+2u7faA2s14aDaF0TaHaJ0DaL5iaN3-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 9A0BcD3Eb86L6NdYb`bX6~fK6c5Zd 0V9pfP9vfna$0V4_f54}f7fwdQf?fR98fYd`fScB0CfHg9bsf~c$6e0N0Ne6cJf*a.8X0Ef-cF3MbM1Efmc$a;5_fZgs7,cCcWf44{g64 gBgG3cfobAgecge5g1glgP1^gngpaZ8Ugrf$6-5 0B9febed1P4F9J4Q9Y0O0HeM5#0A0c0Y0_0:ao0r0-aK2Qaja8aa2|4M0m0j0-a|2q0y0^eV3m0h0Q3m1)bN9=dXex1lah0K3Cep0Q0-9=0Reuew0AgS0l2T32g|9=7s0Nhn16hn1l0_en1=2Q2~0rg4b;9=4M0ThD0^2f0V110s0Q1;0^2Q0{abg|ao4X4N04gd9Eh@0l1y0A0la1epeGeT0l2|1j2p2Ci3h/h20r8N2TdHhL0A3m0Nhk9`04eEeueHeu3ChD0Vg h-5eaaa01:0g2C0^hA0Q9}0A2Qh.aja55g0AhP0K0A0XdB8ib;ap9_1T1Vat1*e#ax7:e)2Ce+0laEeRe.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:jVjI0mfkj%gfg0gCgRfce9d*d{jy3#5Zj3dU7(jnc;0Xdr0sjTj~4g7RfCj(6vb%8Wjwj!6c0K0q14030l0h2:ak5e1;0lfYa72g0^h/0%6sa700h36^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=18itia8N110-0ldScNj+c/lO9cjIj*98lhj2jBgUcug1j7kQj96Wlvk;lslobSk0fr6hlBki04kkhPlG5c0?kqlLai0licf7lQd%kDj`7(dXlel=l0lSf!e6d3k^gHd7jW6j6ek~mf8L9af=g*dmg$fFe9mnkF3#lCl|ak8j2C0l01812ohu0K2tfsmbaTf|j.jIk@j/7;mhlyd!lt92mHmv8:jldAmul361h`4Zee4Gg?eh0Z0_0D0o9;0lh39~1=hP0m9}j21lknm}h,a7iwkrkSna0^0m0a6^0^2|0i0-eRhE0:lE0lkn5Jhyiqiv2ch!9=iIh:ad1=2qkleAg|annei40m1UmOh-0-2M0M2ri39;lJ0lkxkn4SnL2TeO2c1qao0Lkum`m|1za3dK0QhFeoeq0iifeW9J0:lI0c04.