Étant donné une liste unique et triée d'entiers, créez un arbre de recherche binaire équilibré représenté sous forme de tableau sans utiliser de récursivité.
Par exemple:
func( [1,2,3,5,8,13,21] ) => [5,2,13,1,3,8,21]
Avant de commencer, un indice: nous pouvons simplifier ce problème d'une tonne pour ne pas avoir à penser aux entiers d'entrée (ou à tout objet comparable d'ailleurs!).
Si nous savons que la liste d'entrée est déjà triée, son contenu n'a pas d'importance. Nous pouvons simplement y penser en termes d'indices dans le tableau d'origine.
Une représentation interne du tableau d'entrée devient alors:
func( [0,1,2,3,4,5,6] ) => [3,1,5,0,2,4,6]
Cela signifie que plutôt que d'écrire quelque chose qui doit traiter avec des objets comparables, nous n'avons vraiment besoin que d'écrire une fonction qui mappe de la plage [0, n) au tableau résultant. Une fois que nous avons la nouvelle commande, nous pouvons simplement appliquer le mappage aux valeurs de l'entrée pour créer le tableau de retour.
Les solutions valides doivent:
- Acceptez un tableau à zéro élément et renvoyez un tableau vide.
- Acceptez un tableau entier de longueur n et retournez un tableau entier
- D'une longueur comprise entre n et la puissance immédiatement supérieure de 2 moins 1. (par exemple, pour la taille d'entrée 13, retournez entre 13 et 15).
- Tableau qui représente un BST où le nœud racine est à la position 0 et la hauteur est égale à log (n) où 0 représente un nœud manquant (ou une
null
valeur semblable à si votre langue le permet). Les nœuds vides, s'ils sont présents, ne doivent exister qu'à la fin de l'arborescence (par exemple,[2,1,0]
)
Le tableau d'entiers en entrée présente les garanties suivantes:
- Les valeurs sont des entiers signés 32 bits supérieurs à zéro.
- Les valeurs sont uniques.
- Les valeurs sont en ordre croissant à partir de la position zéro.
- Les valeurs peuvent être clairsemées (c'est-à-dire non adjacentes les unes aux autres).
Le code le plus laconique par nombre de caractères ascii gagne, mais je suis également intéressé à voir des solutions élégantes pour une langue particulière.
Cas de test
Les sorties pour les tableaux simples contenant 1
to n
pour divers n
. Comme décrit ci-dessus, les 0
s finaux sont facultatifs.
[]
[1]
[2,1,0]
[2,1,3]
[3,2,4,1,0,0,0]
[4,2,5,1,3,0,0]
[4,2,6,1,3,5,0]
[4,2,6,1,3,5,7]
[5,3,7,2,4,6,8,1,0,0,0,0,0,0,0]
[6,4,8,2,5,7,9,1,3,0,0,0,0,0,0]
[7,4,9,2,6,8,10,1,3,5,0,0,0,0,0]
[8,4,10,2,6,9,11,1,3,5,7,0,0,0,0]
[8,4,11,2,6,10,12,1,3,5,7,9,0,0,0]
[8,4,12,2,6,10,13,1,3,5,7,9,11,0,0]
[8,4,12,2,6,10,14,1,3,5,7,9,11,13,0]
[8,4,12,2,6,10,14,1,3,5,7,9,11,13,15]
la source
Réponses:
Rubis , 143
Il s'agit d'une version (vaguement) compressée du code suivant qui effectue essentiellement un BFS sur l'arborescence.
De plus, parce que c'est BFS, pas DFS, une exigence de solution non récursive n'est pas significative, et elle désavantage certaines langues.
Edit: Solution fixe, merci à @PeterTaylor pour son commentaire!
la source
Java , 252
Ok, voici ma tentative. J'ai joué avec les opérations sur les bits et j'ai trouvé cette façon directe de calculer l'index d'un élément dans le BST à partir de l'index dans le tableau d'origine.
Version compressée
La version longue suit ci-dessous.
la source
int[] b(int[] a)
est tout aussi bien exprimé queint[]b(int[]a)
.a.length
dans l'allocation de tableau. Remplacez-le pars
. Débarrassez-vous de l'espace entrefor (
plusieurs fois. Chaque boucle for crée unint i=0
et aussiint t=0
. Créez avecn
(int n=0,i,t;
) puis justei=0
dans les boucles et à l't=1
intérieur. Déclarez l'intérieurlong x
etlong I
avecs
et initialisez simplement dans la boucle (long s=a.length,I,x;
etx=..
/I=..
). Vous ne devriez pas avoir besoin d'espaces autour du ET binaire&
.I=I|..
peut être écritI|=..
la source
Je ne sais pas si cela correspond exactement à vos besoins de nœuds vides à la fin de l'arbre et cela ne gagnera certainement pas de prix pour la brièveté, mais je pense que c'est correct et qu'il a des cas de test :)
la source
Golfscript (
9989)Fondamentalement, un port direct de ma solution Python fonctionne à peu près de la même manière.
Peut probablement être amélioré un peu avec plus de "golfismes", déjà amélioré de 10 caractères avec l'entrée de @ petertaylor :)
la source
!{;}{}if
peut simplement être!{;}*
parce que les!
garanties de retour0
ou1
. Vous pouvez utiliser des jetons non alphabétiques pour les variables, donc si vous utilisez^
au lieu der
,|
au lieu dex
,&
au lieu de,y
vous pouvez éliminer tout cet espace.Java 192
Mappe l'index en entrée à l'index en sortie
Version longue:
la source
Wolfram Mathematica 11, 175 octets
La fonction
g[l]
prend en entrée aList
(par exemplel={1,2,3,4,...}
) et renvoie aList
de la forme souhaitée. Cela fonctionne comme suit:x[a_]:=Floor@Min[i-#/2,#]&@(i=Length[a]+1;2^Ceiling@Log2[i]/2)
prend une liste et trouve la racine du BST associé.i=Length[a]+1
raccourci pour la longueur de la liste2^Ceiling@Log2[i]/2
limite supérieure sur la valeur de la racineMin[i-#/2,#]&@(...)
Minimum des deux arguments où#
représente ce qui se trouve à l'intérieur du(...)
l//.{...}
Appliquez à plusieurs reprises les règles de remplacement qui suivent pourl
{}->{}
Rien à faire (c'est le cas de bord pour éviter une boucle infinie)b__List:>(n[Take[b,#-1],b[[#]],Drop[b,#]]&@x[b])
Diviser unList
en{{lesser}, root, {greater}}
Cases[...,_Integer,{m}]
Prendre tous les entiers au niveau (profondeur)m
Table[...,{m,1,x[l]}]
Pour tousm
jusqu'àx[l]
(ce qui est plus que nécessaire en fait).Il peut être testé en exécutant
Cette implémentation n'inclut pas les zéros de fin.
la source
Python (
175171)Assez condensé, encore assez lisible;
Il renvoie le résultat, vous pouvez donc le parcourir ou (à des fins d'affichage) l'imprimer sous forme de liste;
la source
Java
Il s'agit d'une solution de calcul direct. Je pense que cela fonctionne, mais il a un effet secondaire pragmatiquement inoffensif. Le tableau qu'il produit peut être corrompu, mais pas d'une manière qui pourrait affecter les recherches. Au lieu de produire 0 noeuds (nuls), il produira des noeuds inaccessibles, c'est-à-dire que les noeuds auront déjà été trouvés plus tôt dans l'arborescence pendant la recherche. Il fonctionne en mappant le tableau d'indices d'une puissance régulière de tableau d'arbre de recherche binaire de taille 2 sur un tableau d'arbre de recherche binaire de taille irrégulière. Au moins, je pense que cela fonctionne.
Voici une version plus condensée (juste la fonction et les noms associés). Il y a toujours un espace blanc, mais je ne suis pas inquiet de gagner. Cette version prend également un tableau. L'autre a juste pris un int pour l'index le plus élevé du tableau.
la source
GolfScript (
79 7770 caractères)Étant donné que l'exemple de la question utilise une fonction, j'en ai fait une fonction. Supprimer le
{}:f;
pour laisser une expression qui prend une entrée sur la pile et laisse le BST sur la pile économiserait 5 caractères.Démo en ligne (note: l'application peut prendre un peu de temps pour s'échauffer: elle a expiré deux fois pour moi avant de fonctionner en 3 secondes).
Avec un espace pour montrer la structure:
la source
J , 52 octets
la fonction prend une liste triée et retourne dans l'ordre de l'arbre binaire
remarquez que les arbres ont une forme identique mais le niveau du fond est raccourci
`1:
commencer par 1<.@(2&^.)@>:@#
itérer par étage de log2 (longueur + 1)+: , >:@+:@i.@>:@#
boucle: ajoute le double du dernier vecteur avec des nombres impairs 1,3 .. 2 * longueur + 1# /:@{.
prendre uniquement le nombre requis d'éléments et obtenir leurs indices de tri/:
appliquer ces indices de tri à l'entrée donnéeTIO
la source
Python 2 , 107 octets
Réponse de Golf of Joachim Isaksson , Input est un singleton contenant la liste.
Essayez-le en ligne!
la source