Reversing binary tree

I heard about this task. For example, we have a tree
   4
  2 6
1 3 5 7
and we need to flip it over vertivcal to have in result
   4
  6 2
7 5 3 1
Easy to see that we need traverse the tree and just exchange left and right node refs.
In golang, I would create struct like this.

type Node struct {
Value int
Left  *Node
Right *Node
}

First thing, that I can ask myself - how to traverse tree?
E.g. recursion, horizontal.

Recursion is easy to implement


func reverseBinaryTreeRecursive(n *Node) {
if n != nil {
t := n.Left
n.Left = n.Right
n.Right = t
reverseBinaryTreeRecursive(n.Left)
reverseBinaryTreeRecursive(n.Right)
}
}

go to node, flip left and right, execute the same on both nodes.

Add all nodes to kind of queue and process it


func reverseBinaryTreeQueued(root *Node) {
nodes := list.New()
nodes.PushBack(root)
for e := nodes.Front(); e != nil; e = e.Next() {
n := e.Value.(*Node)
if n != nil {
t := n.Left
n.Left = n.Right
n.Right = t
nodes.PushBack(n.Left)
nodes.PushBack(n.Right)
}
}
}

Whole golang implementation

package algos

import (
"container/list"
"fmt"
"log"
)

type way int

const (
queued    way = 1
recursive way = 2
)

type Node struct {
Value int
Left  *Node
Right *Node
}

func BinaryTreeDemo() {
n1 := &Node{1, nil, nil}
n3 := &Node{3, nil, nil}
n2 := &Node{2, n1, n3}
n5 := &Node{5, nil, nil}
n7 := &Node{7, nil, nil}
n6 := &Node{6, n5, n7}
n4 := &Node{4, n2, n6}

reverseBinaryTree(n4, recursive)
}

func reverseBinaryTree(root *Node, w way) {
fmt.Println("\nbefore reverse")
printBinaryTree(root)
switch w {
case queued:
reverseBinaryTreeQueued(root)
case recursive:
reverseBinaryTreeRecursive(root)
}
fmt.Println("\n\nafter reverse")
printBinaryTree(root)
}

func reverseBinaryTreeRecursive(n *Node) {
if n != nil {
t := n.Left
n.Left = n.Right
n.Right = t
reverseBinaryTreeRecursive(n.Left)
reverseBinaryTreeRecursive(n.Right)
}
}

func reverseBinaryTreeQueued(root *Node) {
nodes := list.New()
nodes.PushBack(root)
for e := nodes.Front(); e != nil; e = e.Next() {
n := e.Value.(*Node)
if n != nil {
t := n.Left
n.Left = n.Right
n.Right = t
nodes.PushBack(n.Left)
nodes.PushBack(n.Right)
}
}
}

type DeepNode struct {
Node *Node
Deep int
}

func printBinaryTree(root *Node) {
nodes := list.New()
if root == nil {
log.Println("empty")
return
}
deep := 0
nodes.PushBack(&DeepNode{root, deep})
for e := nodes.Front(); e != nil; e = e.Next() {
n := e.Value.(*DeepNode)
if deep != n.Deep {
deep = n.Deep
fmt.Println()
}
fmt.Print(n.Node.Value, " ")

if n.Node.Left != nil {
nodes.PushBack(&DeepNode{n.Node.Left, n.Deep + 1})
}
if n.Node.Right != nil {
nodes.PushBack(&DeepNode{n.Node.Right, n.Deep + 1})
}
}
}

Java, do the same


Similar code, different syntax

package algos;

import algos.ReversingBinaryTree.DeepNode;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ReversingBinaryTree {

    enum Way {
        Queued,
        Recursive
    }

    class Node {

        int value;
        Node left;
        Node right;

        Node(int value, Node left, Node right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
    }

    class DeepNode {

        Node node;
        int deep;

        private DeepNode(Node node, int deep) {
            this.node = node;
            this.deep = deep;
        }
    }

    void binaryTreeDemo() {
        Node n1 = new Node(1, null, null);
        Node n3 = new Node(3, null, null);
        Node n2 = new Node(2, n1, n3);
        Node n5 = new Node(5, null, null);
        Node n7 = new Node(7, null, null);
        Node n6 = new Node(6, n5, n7);
        Node n4 = new Node(4, n2, n6);

        reverseBinaryTree(n4, Way.Recursive);
    }

    void reverseBinaryTree(Node root, Way w) {
        System.out.println("\nbefore reverse");
        printBinaryTree(root);
        switch (w) {
            case Queued:
                reverseBinaryTreeQueued(root);
                break;
            case Recursive:
                reverseBinaryTreeRecursive(root);
                break;
        }
        System.out.println("\n\nafter reverse");
        printBinaryTree(root);
    }

    void reverseBinaryTreeRecursive(Node n) {
        if (n != null) {
            Node t = n.left;
            n.left = n.right;
            n.right = t;
            reverseBinaryTreeRecursive(n.left);
            reverseBinaryTreeRecursive(n.right);
        }
    }

    void reverseBinaryTreeQueued(Node root) {
        List<Node> nodes = new ArrayList<>();
        nodes.add(root);
        for (Node n : nodes) {
            Node t = n.left;
            n.left = n.right;
            n.right = t;
            nodes.add(n.left);
            nodes.add(n.right);
        }
    }

    void printBinaryTree(Node root) {
        if (root == null) {
            System.out.println("empty");
            return;
        }
        int deep = 0;

        List<DeepNode> nodes = new LinkedList<>();
        nodes.add(new DeepNode(root, deep));
        for (int i = 0; i < nodes.size(); i++) {
            DeepNode n = nodes.get(i);
            if (deep != n.deep) {
                deep = n.deep;
                System.out.println();
            }
            System.out.print(n.node.value + " ");

            if (n.node.left != null) {
                nodes.add(new DeepNode(n.node.left, n.deep + 1));
            }
            if (n.node.right != null) {
                nodes.add(new DeepNode(n.node.right, n.deep + 1));
            }
        }
    }

    public static void main(String[] args) {
        new ReversingBinaryTree().binaryTreeDemo();
    }
}

Popular Posts