Je travaille actuellement sur "Algorithms in java" de Robert Sedgewick (3ème édition, version allemande) et j'essaie de résoudre l'un des exercices là, actuellement un de la section "creative-solutions".Trier un arbre non ordonné par la quantité de nœuds-enfants qu'un nœud a
Dans le cadre de la solution d'un exercice que je suis en train de trier un arbre par la quantité non triés des enfants chaque noeud a, noeuds avec des quantités plus grandes d'enfants venant en premier:
- Trier tous les nœuds enfants d'un parent n0 selon la quantité de nœuds enfants
nNodes
que possèdent les nœuds enfants eux-mêmes, trier de gauche à droite du plus grand au plus bas. Effectuez ce tri pour tous les nœuds de l'arborescence. - Si 2 noeuds-frères n1 et n2 de ces noeuds-enfants ont
nNodes
identiques, allez aux noeuds-enfants de n1 et n2 essayez de trier ces deux-là en fonction dunNodes
de leurs plus grands enfants. Si aucune différence n'est trouvée, essayez de trier en fonction dunNodes
de leurs 2e plus grands enfants, etc. - Si vous n'avez plus d'enfants, rendez-vous au nœud d'enfant de l'enfant dans 2 avec le plus grand nombre d'enfants et répétez 2. etc. etc.
- Si, après toutes les comparaisons, il s'avère que n1 et n2 sont tous deux des racines d'arbres de forme identique, peu importe lequel des deux vient en premier.
Pour donner une comparaison visuelle, cette « règle » entraînerait le tri des arbres suivant comme décrit ici: Example of Sorting.
Le code
Le problème que je suis bloqué à la mise en œuvre est correctement le tri. Chaque arbre est composé de nœuds. Chaque nœud contient une valeur (de sorte que vous avez un "nom" pour le nœud, pas important pour le tri lui-même qui ne se soucie que du nombre d'enfants de chaque nœud) et une liste de références de nœuds aux nœuds enfants de ce nœud nœud. Pour les nœuds sans enfants, ArrayList a la taille 0. La clé consiste ici à trier les ArrayLists dans tous les nœuds, ce que j'essaie actuellement de faire en utilisant la méthode de tri intégrée avec un objet Comparator. Je pense que je dois aborder cela de façon récursive, ce qui rend le tout vraiment désordonné parce que j'ai actuellement une méthode de comparaison qui s'appelle tout en appelant "sort" pour d'autres ArraLists dans la même méthode. La méthode sortForest
ci-dessous me donne des erreurs de débordement de pile lorsque je l'essaye dans certaines méthodes principales pour le tester.
static NodeComparator comp = new NodeComparator();
static class Node {
int value;
ArrayList<Node> children;
Node(int value, ArrayList<Node> children) {
this.value = value;
this.children = children;
}
}
static class NodeComparator implements Comparator<Node> {
public NodeComparator() {
}
public int compare(Node n1, Node n2) {
/*-
* Base Case 1: Both Nodes are leafs (isEmpty() is true) - they are
* equal -> return 0.
* Base Case 2/3: One of the Nodes is a leaf while the other isn't -
* the one that is a leaf is "lower" than the one that isn't. ->
* return (-) 1.
*/
if (n1.children.isEmpty() && n2.children.isEmpty()) {
return 0;
} else if (n2.children.isEmpty()) {
n1.children.sort(comp);
return 1;
} else if (n1.children.isEmpty()) {
n2.children.sort(comp);
return -1;
} else {
/* Get the amount of children the 2 nodes n1 and n2 have */
int nChildren1 = (n1.children.isEmpty()) ? 0 : n1.children.size();
int nChildren2 = (n2.children.isEmpty()) ? 0 : n2.children.size();
/* Always sort the ArrayList of children that they have */
n1.children.sort(comp);
n2.children.sort(comp);
/*
* If n1 and n2 have equal amounts of children, compare the
* amounts of children their children have, from largest to
* lowest
*/
if (nChildren1 == nChildren2) {
int result = 0;
for (int i = 0; (i < nChildren1) && (result == 0); i++) {
compare(n1.children.get(i), n2.children.get(i));
}
return result;
} else {
/*- If one node has more children than the other, sort accordingly */
return ((nChildren1 > nChildren2) ? 1 : -1);
}
}
}
}
static void sortForest(Node root) {
for (int i = 0; i < root.children.size(); i++) {
sortForest(root.children.get(i));
root.children.sort(comp);
}
return;
}
Question
Comment peut-on obtenir ce code au travail? Je suis un peu sûr que c'est à peu près dans le cadre d'une solution correcte, mais j'ai essayé de réfléchir à cela pendant plusieurs heures maintenant et je n'arrive pas à en trouver un. Je suis convaincu que cela me donne des débordements de pile en raison d'une récursion sans fin qui se trouve quelque part, je ne le vois tout simplement pas. La récursivité en général me donne des problèmes pour le faire correctement mentalement. Je ne pouvais pas trouver des questions identiques à ceci et ceux qui étaient semblables se sont occupés des arbres binaires au lieu des unsordered.
Le test-arbre, je suis en cours d'exécution a actuellement 14 nœuds, donc je suis actuellement convaincu que je suis quelque part là-bas ayant une récursivité sans fin. J'aurais dû le mentionner dans la question principale, je vais le modifier. – Isofruit