Donc, avant de lire quelques concepts informatiques de base.
- Un arbre binaire est une structure allouée dynamiquement (généralement utilisée pour le stockage ordonné).
- En raison de sa nature, la traversée d'arbres binaires est généralement récursive;
En effet, la traversée linéaire (via une boucle) n'est pas naturelle lorsqu'il existe deux voies de bouclage.- Récursif: cela signifie une fonction qui s'appelle elle-même.
- Dans les langues anciennes, la gestion de la mémoire nécessite une gestion manuelle de la mémoire.
- Manuel: signifie que vous devez le faire vous-même.
- Lorsque vous effectuez une gestion manuelle de la mémoire, vous devez demander au système sous-jacent de libérer chaque membre de l'arborescence.
- Gratuit: récupérez la mémoire dans le caca mondial afin qu'elle puisse être réutilisée et que vous ne manquiez pas de mémoire.
- Libération: cela se fait en appelant la fonction
free()
et en lui passant le pointeur que vous souhaitez récupérer. - Pointeur: C'est comme un bâton virtuel. À la fin, c'est la mémoire. Lorsque vous demandez de la mémoire, vous recevez un pointeur (bâton virtuel) qui a de la mémoire. Lorsque vous avez terminé, vous rendez le pointeur (bâton virtuel).
La solution récursive:
freeTree(Node* node)
{
freeTree(node->left);
freeTree(node->right);
free(node);
}
Le problème est alors que la récursivité signifie que vous appelez à plusieurs reprises la même fonction. Cela augmente la pile. Agrandir la pile utilise plus de mémoire. La raison pour laquelle vous libérez l'arborescence est que vous souhaitez récupérer de la mémoire en utilisant plus de mémoire est contre-productif (même si vous récupérez les deux bits de mémoire).
Enfin la question:
Le problème se concentre donc sur la conversion de la version récursive ci-dessus en une solution linéaire (de sorte que vous n'ayez pas à utiliser de mémoire).
Donnez le type de nœud
typedef struct Node Node;
struct Node
{
Node* left;
Node* right;
};
Écrivez une fonction pour libérer un arbre de ces nœuds.
Restrictions:
- Ne peut pas utiliser la récursivité (pas même indirectement)
Impossible d'allouer d'espace dynamique pour le suivi.
Notez qu'il existe une solution O (n)
Gagnant:
- Meilleure complexité.
- Tie Break 1: première soumission
- Tie Break 2: moins de personnages.
la source
C99, 94, O (n)
Edit: tout le monde semble se référer à
struct Node
tout commeNode
comme si l'typedef
Éd, donc je l'ai fait aussi.c'est en fait mon premier golf C. beaucoup de segfaults.
de toute façon, cela nécessite C99 car il utilise une déclaration à l'intérieur de la première instruction d'une boucle for.
n'utilisant même pas
#define
!cet algorithme fonctionne en transformant l'arborescence de sorte que le nœud supérieur n'a pas d'enfant gauche, puis en le supprimant et en passant à son enfant droit.
par exemple, si nous commençons par l'arbre
l'algorithme mute les pointeurs afin que l'arbre soit
nous pouvons maintenant supprimer facilement le nœud le plus haut.
la source
C / C ++ / Objective-C 126 caractères (inclut la nouvelle ligne de fin requise)
Ne fonctionne pas en temps O (n). Mais l'OP ne l'exige pas, voici donc ma solution O (n 2 ).
Algorithme: descendez jusqu'à une feuille depuis la racine. Publiez-le. Répétez jusqu'à ce qu'il n'y ait pas de feuilles. Relâchez la racine.
Non golfé:
la source
c ++ 99 O (n)
Les boucles ici sont parfaites pour enchaîner une liste mais pas pour monter et descendre des hiérarchies. user300 l'a géré (je suis impressionné) mais le code est difficile à lire.
La solution consiste à convertir l'arborescence en liste.
L'astuce consiste à le faire en même temps que vous supprimez les nœuds.
Version Golf
Golf élargi
la source
C, 150 octets
Essayez-le sur JDoodle
la source