Inverser un arbre binaire (de gauche à droite))
je regardais les questions d'entrevue et je suis récemment tombé sur un qui vous a demandé comment inverser un arbre binaire général, comme le retourner de droite à gauche.
Donc par exemple, si nous avions de l'arbre binaire
6
/
3 4
/ /
7 3 8 1
L'Inverser créerait
6
/
4 3
/ /
1 8 3 7
Je n'ai pas été capable de penser à une bonne implémentation sur la façon de résoudre ce problème. Quelqu'un peut-il proposer de bonnes idées?
Merci
9 réponses
Vous pouvez utiliser la récursivité:
static void reverseTree(final TreeNode root) {
final TreeNode temp = root.right;
root.right = root.left;
root.left = temp;
if (root.left != null) {
reverseTree(root.left);
}
if (root.right != null) {
reverseTree(root.right);
}
}
sur la Base des commentaires:
static void reverseTree(final TreeNode root) {
if (root == null) {
return;
}
final TreeNode temp = root.right;
root.right = root.left;
root.left = temp;
reverseTree(root.left);
reverseTree(root.right);
}
inverser un arbre binaire dans O(1).
struct NormalNode {
int value;
struct NormalNode *left;
struct NormalNode *right;
};
struct ReversedNode {
int value;
struct ReversedNode *right;
struct ReversedNode *left;
};
struct ReversedNode *reverseTree(struct NormalNode *root) {
return (struct ReversedNode *)root;
}
il y a quelques parties intéressantes à cette question. Tout d'abord, puisque votre langue est Java, vous êtes le plus susceptible d'avoir un noeud Générique classe, quelque chose comme ceci:
class Node<T> {
private final T data;
private final Node left;
private final Node right;
public Node<T>(final T data, final Node left, final Node right) {
this.data = data;
this.left = left;
this.right = right;
}
....
}
Deuxièmement, l'inversion, parfois appelée inversion, peut être faite soit en Mutant les champs gauche et droite du noeud, soit en créant un noeud comme l'original mais avec ses enfants gauche et droite "inversé."La première approche est illustrée en une autre répondre à, alors que la seconde approche est montrée ici:
class Node<T> {
// See fields and constructor above...
public Node<T> reverse() {
Node<T> newLeftSubtree = right == null ? null : right.reverse();
Node<T> newRightSubtree = left == null ? null : left.reverse();
return Node<T>(data, newLeftSubtree, newRightSubtree);
}
}
L'idée de ne pas la mutation d'une structure de données est l'une des idées derrière structures de données persistantes, qui sont assez intéressants.
Il y a beaucoup de façons de faire pour vous et beaucoup de gens diront faire beaucoup de nouvelles réponses, mais la meilleure façon de résoudre les questions de l'arbre(presque) avec l'aide de la récursion et en utilisant ceci vous pouvez résoudre tous les autres problèmes liés à l'arbre.
voici donc la solution pour vous que comment vous pouvez inverser l'arbre binaire -
pour cela ce que vous aurez à faire est à chaque pas nous devons échanger gauche et droite enfant du parent donc utiliser la fonction swap pour échanger pour gauche et droite l'enfant et faire ce processus pour leurs enfants aussi.
void reversetree(struct node* head)
{
//first check for the exception whether does it even exit or not
if(head==NULL)
return ;
reversetree(head->left); //reverse call for left child
reversetree(head->right); //same reverse call for right child
//now next these steps will swap the children
struct node* temp=head->left;
head->left=head->right;
head->right=head->left;
//now exit the function and you are done :)
}
modifier la traversée de pré-ordre pour retourner les noeuds avant de traverser davantage.
#python3
def flipTree(node):
if node is None:
return
#flip nodes
node.left,node.right = node.right,node.left
flipTree(node.left)
flipTree(node.right)
vous pouvez changer récursivement les noeuds gauche et droite comme ci-dessous;
// helper method
private static void reverseTree(TreeNode<Integer> root) {
reverseTreeNode(root);
}
private static void reverseTreeNode(TreeNode<Integer> node) {
TreeNode<Integer> temp = node.left;
node.left = node.right;
node.right = temp;
if(node.left != null)
reverseTreeNode(node.left);
if(node.right != null)
reverseTreeNode(node.right);
}
Démonstration de Code Java
import java.util.LinkedList;
import java.util.Queue;
public class InvertBinaryTreeDemo {
public static void main(String[] args) {
// root node
TreeNode<Integer> root = new TreeNode<>(6);
// children of root
root.left = new TreeNode<Integer>(3);
root.right = new TreeNode<Integer>(4);
// grand left children of root
root.left.left = new TreeNode<Integer>(7);
root.left.right = new TreeNode<Integer>(3);
// grand right childrend of root
root.right.left = new TreeNode<Integer>(8);
root.right.right = new TreeNode<Integer>(1);
System.out.println("Before invert");
traverseTree(root);
reverseTree(root);
System.out.println("\nAfter invert");
traverseTree(root);
}
// helper method
private static void reverseTree(TreeNode<Integer> root) {
reverseTreeNode(root);
}
private static void reverseTreeNode(TreeNode<Integer> node) {
TreeNode<Integer> temp = node.left;
node.left = node.right;
node.right = temp;
if(node.left != null)
reverseTreeNode(node.left);
if(node.right != null)
reverseTreeNode(node.right);
}
// helper method for traverse
private static void traverseTree(TreeNode<Integer> root) {
Queue<Integer> leftChildren = new LinkedList<>();
Queue<Integer> rightChildren = new LinkedList<>();
traverseTreeNode(root, leftChildren, rightChildren);
System.out.println("Tree;\n*****");
System.out.printf("%3d\n", root.value);
int count = 0;
int div = 0;
while(!(leftChildren.isEmpty() && rightChildren.isEmpty())) {
System.out.printf("%3d\t%3d\t", leftChildren.poll(), rightChildren.poll());
count += 2;
div++;
if( (double)count == (Math.pow(2, div))) {
System.out.println();
count = 0;
}
}
System.out.println();
}
private static void traverseTreeNode(TreeNode<Integer> node, Queue<Integer> leftChildren, Queue<Integer> rightChildren) {
if(node.left != null)
leftChildren.offer(node.left.value);
if(node.right != null)
rightChildren.offer(node.right.value);
if(node.left != null) {
traverseTreeNode(node.left, leftChildren, rightChildren);
}
if(node.right != null) {
traverseTreeNode(node.right, leftChildren, rightChildren);
}
}
private static class TreeNode<E extends Comparable<E>> {
protected E value;
protected TreeNode<E> left;
protected TreeNode<E> right;
public TreeNode(E value) {
this.value = value;
this.left = null;
this.right = null;
}
}
}
Sortie
Before invert
Tree;
*****
6
3 4
7 3 8 1
After invert
Tree;
*****
6
4 3
1 8 3 7
la fonction de récursion peut être très simple comme suit:
public Node flipTree(Node node) {
if(node == null) return null;
Node left = flipTree(node.left);
Node right = flipTree(node.right);
node.left = right;
node.right = left;
return node;
}
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution
{
public TreeNode root;
public TreeNode InvertTree(TreeNode root)
{
if (root == null)
return null;
Swap(root);
InvertTree(root.left);
InvertTree(root.right);
return root;
}
public void Swap(TreeNode root)
{
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
}
}
public class ReverseBinaryTree
{
public void Test()
{
Solution tree = new Solution();
tree.root = new TreeNode(1);
tree.root.left = new TreeNode(2);
tree.root.right = new TreeNode(3);
tree.root.left.left = new TreeNode(4);
tree.root.left.right = new TreeNode(5);
tree.InvertTree(tree.root);
Console.ReadLine();
}
}
j'ai vu que la plupart des réponses ne se concentrent pas sur les problèmes de pointeur nul.
public static Node invertBinaryTree(Node node) {
if(node != null) {
Node temp = node.getLeftChild();
node.setLeftChild(node.getRightChild());
node.setRigthChild(temp);
if(node.left!=null) {
invertBinaryTree(node.getLeftChild());
}
if(node.right !=null) {
invertBinaryTree(node.getRightChild());
}
}
return node;
}
dans le code ci-dessus nous faisons des appels récursifs seulement si l'enfant gauche/droite du noeud racine n'est pas nul. Son un de la manière la plus rapide approche!