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.
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.
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)
}
}
}
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})
}
}
}
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();
}
}
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 algosimport (
"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();
}
}