Les arbres de recherche binaires équilibrés sont essentiels pour garantir les recherches O (log n) (ou opérations similaires). Dans un environnement dynamique où de nombreuses clés sont insérées et / ou supprimées au hasard, les arbres peuvent dégénérer en listes liées qui sont horribles pour les recherches. Il existe donc différents types d' arbres binaires à équilibrage automatique qui neutralisent cet effet (tels que les arbres AVL ou les arbres évasés ). Ces arbres sont basés sur différents types de rotations qui rééquilibrent l'arbre.
Rotations
Dans ce défi, nous ne regarderons que les rotations à droite simples, une telle rotation (la rotation à gauche serait symétrique) ressemble à ceci:
5 3
/ \ / \
3 6 => 1 5
/ \ / \
1 4 4 6
Si l'une des feuilles 1
, 4
ou 6
avait des sous-arbres gauche ou droit, une rotation les garderait simplement là. S'il s'agit d'un sous-arbre d'un arbre plus grand, nous devons simplement le «couper» au nœud 5
et «rattacher» l'arbre pivoté (maintenant le nœud 3
) à ce nœud.
Défi
Étant donné un arbre de recherche binaire 1 et une clé, tournez à droite l'arbre sur ce nœud comme décrit ci-dessus. La clé fournie dans l'exemple ci-dessus serait 5
.
Règles et E / S
- vous pouvez utiliser n'importe quel type de clé tant qu'il y a une bijection entre les clés de votre choix et celles des cas de test
- vous pouvez choisir n'importe quelle représentation pour les arbres binaires tant qu'il n'y a pas d'ambiguïté (par exemple,
[3,[]]
est ambigu sauf indication contraire) et c'est naturel pour la langue de votre choix - comme l'entrée sera toujours un arbre de recherche binaire, il n'y a pas de clés en double
- vous pouvez supposer que la clé est contenue dans l'arborescence
- vous pouvez supposer que le nœud contenant la clé a un enfant gauche
- vous ne pouvez pas supposer un sous-arbre droit sous la clé fournie
- vous ne pouvez pas supposer que l'arbre est déséquilibré avant la rotation
- vous ne pouvez pas supposer que l'arbre est équilibré après la rotation
- vous pouvez utiliser n'importe quelle méthode d'E / S par défaut
- votre soumission peut être une fonction renvoyant l'arborescence ou un programme complet imprimant la solution
Cas de test
Ces exemples représentent un arbre comme suit
- si c'est une feuille:
[]
- si c'est un arbre avec clé
x
et que les deux sous-arbres sont des feuilles:[x]
- si c'est un arbre avec clé
x
et sous-arbresleft
right
:[x,left,right]
Le premier exemple est celui fourni dans la section Rotations . Si pour une raison quelconque , vous avez besoin d' une représentation graphique d'entre eux, ici 2 vous allez.
5 [5,[3,[1],[4]],[6]] -> [3,[1],[5,[4],[6]]]
5 [5,[3,[1],[4]],[]] -> [3,[1],[5,[4],[]]]
5 [5,[3,[],[4]],[6]] -> [3,[],[5,[4],[6]]]
5 [5,[3,[1],[]],[]] -> [3,[1],[5]]
4 [8,[4,[2,[1],[3]],[6,[5],[7]]],[12,[10,[9],[11]],[14,[13],[15]]]] -> [8,[2,[1],[4,[3],[6,[5],[7]]]],[12,[10,[9],[11]],[14,[13],[15]]]]
8 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]] -> [10,[6,[4,[2,[],[3]],[5]],[8,[7],[9]]],[11]]
10 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]] -> [8,[6,[4,[2,[],[3]],[5]],[7]],[10,[9],[11]]]
9 [6,[3,[2],[5]],[9,[8],[12,[11],[15,[14],[]]]]] -> [6,[3,[2],[5]],[8,[],[9,[],[12,[11],[15,[14],[]]]]]]
7 [7,[5,[3,[1],[4]],[6]],[8]] -> [5,[3,[1],[4]],[7,[6],[8]]]
15 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]] -> [17,[9,[5,[2,[0],[4]],[8]],[13,[11,[10],[12]],[15,[14],[16]]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
21 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]] -> [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[19,[18],[21,[20],[24,[22],[25]]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
1: ce qui signifie que pour tout noeud, toutes les clés du sous-arbre gauche seront plus petites que cette clé et toutes les clés du sous-arbre droit seront plus grandes que
2: pour éviter la pourriture des liens, je les ai intégrés en tant que commentaire
data B=B[B]Int
permettrait d'économiser quelques octets supplémentaires.k<n=B[k!l,r]n
puisk>n=B[l,k!r]n
en un seulk/=n=B[k!l,k!r]n
:, puis en ajoutantk!x=x
pour rendre la correspondance de modèle exhaustive.Vim , 25 octets
Prend l'entrée dans la clé et l'arborescence séparées par un espace. L'arbre devrait être représenté comme suit:
[]
k
, enfant gauche<left>
et enfant droit<right>
:[ k <left><right>]
Pas les espaces autour de la clé
k
qui sont importants, tels que la solution fonctionne pour les arbres arbitraires.Essayez-le en ligne!
Explication
Aperçu
Voici un aperçu du premier scénario de test, généré avec ce script par Lynn :
la source
Wolfram Language (Mathematica) , 30 octets
Essayez-le en ligne!
Un arbre représenté comme suit:
$
(vous pouvez la remplacer par n'importe quelle valeur qui n'est pas une clé)x
et sous-arbresleft
right
:x[left,right]
Par exemple, l'arborescence du premier scénario de test est représentée par
5[3[1[$,$],4[$,$]],6[$,$]]
.Explication:
la source
Lisp commun, 146 octets
Essayez-le en ligne ou vérifiez tous les tests!
Un arbre est représenté comme suit:
nil
(ou de manière équivalente en Common Lisp comme la liste vide()
)(node left-subtree right-subtree)
(donc une feuilleL
est représentée comme(L nil nil)
).la source
JavaScript (Node.js) , 70 octets
Essayez-le en ligne! Le lien inclut des cas de test. Tous les nœuds doivent avoir des entrées gauche et droite mais ils peuvent
[]
indiquer aucun sous-arbre de ce côté. Comme abréviation, la suite de tests utilisel(N)
pour indiquer qu'ilN
s'agit d'une feuille etl(N,L)
pour indiquer qu'elleN
a un sous-arbre gaucheL
mais pas de sous-arbre droit à la fois en entrée et en sortie.la source
Python 2 , 85 octets
Essayez-le en ligne!
Format d'entrée:
[KEY, LEFT_SUBTREE, RIGHT_SUBTREE]
[]
la source
Gelée , 24 octets
Essayez-le en ligne!
Avertissement: Normalement, la ligne supérieure ne devrait pas exister et la ligne inférieure devrait avoir un
ß
, pas unç
. Cependant, des astuces de chaîne intelligentes etß
ne vont pas bien ensemble, en raison deß
arité variable de. Techniquement, j'aurais pu encore omettre la ligne supérieure, mais le résultat aurait dû être un programme complet, car sinon il devrait pouvoir être incorporé comme sa propre ligne dans n'importe quel programme, ce qui n'est possible que si vous suis chanceux. Cela signifie que, malheureusement, la sortie aurait eu une représentation ambiguë, car, lorsque vous soumettez un programme complet, ce qui obtient réellement la sortie compte, et non ce que le résultat est techniquement avant la fermeture du programme. Donc, afin de ne pas gâcher à la fois la récursivité et la représentation correcte des chaînes, j'ai décidé de soumettre une fonction à 2 lignes, où le travail de la ligne supérieure consiste simplement à appeler la fonction inférieure. La conséquence? Un énorme gaspillage de 2 octets précieux et précieux. Dans la défense de Jelly (et Dennis, ainsi que de tous les autres contributeurs),la source