Monday, May 7, 2012

A good looking tree program

This is the a full code for creating a Tree Data Structure in Java. This class will be able to create modify and display a tree.

package com.test.ds;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class TreeAppLL {

 private TreeNodeLL root;

 public TreeAppLL(TreeNodeLL root) {
  this.root = root;
 }
 
 public TreeNodeLL getRoot(){
  return this.root;
 }

 /**
  * Find the code. We are assuming we have a inorder tree
  * 
  * @param key
  * @return
  */
 public TreeNodeLL find(int key) {
  TreeNodeLL current = root;
  while (current.key != key) {
   if (key > current.key) {
    current = current.leftChild;
   } else {
    current = current.rightChild;
   }
   if (current == null) {
    return null;
   }
  }
  return current;
 }

 public void insert(int key, int data) {
  TreeNodeLL node = new TreeNodeLL(key, data);
  if (root == null) {
   root = node;
  }
  /*
   * So we have to insert after some node.
   */
  else {
   TreeNodeLL current = root;
   TreeNodeLL parent;
   while (true) {
    parent = current;
    if (key < current.key) {
     current = current.leftChild;
     if (current == null) {
      parent.leftChild = node;
      return;
     }
    } else {
     current = current.rightChild;
     if (current == null) {
      parent.rightChild = node;
      return;
     }
    }
   }
  }
 }

 public void traversal() throws IOException {
  do {
   System.out.println("Enter the choice");
   System.out.println("1. In Order");
   System.out.println("2. Post Order");
   System.out.println("3. Pre Order");
   System.out.println("Press 'e' to Exit ");
   System.out.print("Choice: ");
   String str = getInput();
   if (str.equalsIgnoreCase("e")) {
    break;
   }
   switch (Integer.parseInt(str)) {
   case 1:
    System.out.println("In order traversal is: ");
    inOrder(root);
    System.out.println("");
    break;
   case 2:
    System.out.println("Post order traversal is: ");
    postOrder(root);
    System.out.println("");
    break;
   case 3:
    System.out.println("Pre order traversal is: ");
    preOrder(root);
    System.out.println("");
    break;
   default:
    inOrder(root);
    System.out.println("");
    break;
   }
  } while (true);
 }

 private void inOrder(TreeNodeLL current) {
  if (current != null) {
   inOrder(current.leftChild);
   System.out.print(" " + current.key + " ");
   inOrder(current.rightChild);
  }
 }

 private void postOrder(TreeNodeLL current) {
  if (current != null) {
   postOrder(current.leftChild);
   postOrder(current.rightChild);
   System.out.print(" " + current.key + " ");
  }
 }

 private void preOrder(TreeNodeLL current) {
  if (current != null) {
   System.out.print(" " + current.key + " ");
   preOrder(current.leftChild);
   preOrder(current.rightChild);
  }
 }

 public boolean delete(int key) {
  TreeNodeLL current = root;
  TreeNodeLL parent = root;
  boolean isChildLeft = false;
  while (current.key != key) {
   parent = current;
   if (key < current.key) {
    isChildLeft = true;
    current = current.leftChild;
   } else {
    isChildLeft = false;
    current = current.rightChild;
   }
   if (current == null) {
    return false;
   }
  }

  /**
   * Case 1. Where the both the child nodes are null
   */
  if (current.leftChild == null && current.rightChild == null) {
   if (isChildLeft) {
    parent.leftChild = null;
   } else {
    parent.rightChild = null;
   }
  }
  /**
   * Case 2: where node to be deleted has one child
   * 
   */
  if (current.leftChild == null) {
   if (current == root) {
    root = current.rightChild;
   }
   if (isChildLeft) {
    parent.leftChild = current.rightChild;
   } else {
    parent.rightChild = current.rightChild;
   }
  } else if (current.rightChild == null) {
   if (current == root) {
    root = current.leftChild;
   }
   if (isChildLeft) {
    parent.leftChild = current.leftChild;
   } else {
    parent.rightChild = current.leftChild;
   }
  }

  /**
   * Case 3: When node to be deleted has both the children
   */
  else {
   TreeNodeLL successor = successor(current);
   if (current == root) {
    root = successor;
   } else if (isChildLeft) {
    parent.leftChild = successor;
   } else {
    parent.rightChild = successor;
   }
   successor.leftChild = current.leftChild;
  }
  return true;
 }

 /**
  * return the inorder Successor of sent node
  * 
  * @param delNode
  * @return
  */
 public TreeNodeLL successor(TreeNodeLL delNode) {
  TreeNodeLL current = delNode.rightChild;
  TreeNodeLL sussessorParent = delNode;
  TreeNodeLL sussessor = delNode;
  while (current != null) {
   sussessorParent = sussessor;
   sussessor = current;
   current = current.leftChild;
  }
  if (sussessor != delNode.rightChild) {
   sussessorParent.leftChild = sussessor.rightChild;
   sussessor.rightChild = delNode.rightChild;
  }
  return sussessor;
 }

 public void displayTree() {
  Stack globalStack = new Stack();
  globalStack.push(root);
  int nBlank = 32;
  boolean isRowBlank = false;
  System.out
    .println("-------------------------------------------------------------");
  while (isRowBlank == false) {
   Stack localStack = new Stack();
   isRowBlank = true;

   for (int i = 0; i < nBlank; i++) {
    System.out.print(" ");
   }

   while (globalStack.isEmpty() == false) {
    TreeNodeLL temp = globalStack.pop();
    if (temp != null) {
     System.out.print(temp.key + "," + temp.leftSum+ "," + temp.rightSum);
     localStack.push(temp.leftChild);
     localStack.push(temp.rightChild);

     if (temp.leftChild != null || temp.rightChild != null) {
      isRowBlank = false;
     }
    } else {
     System.out.print("--");
     localStack.push(null);
     localStack.push(null);
    }
    for (int j = 0; j < nBlank * 2 - 2; j++) {
     System.out.print(" ");
    }
   }

   System.out.println("");
   nBlank = nBlank / 2;
   while (localStack.isEmpty() == false) {
    globalStack.push(localStack.pop());
   }
  }
  System.out.println("---------------------------------------------");
 }

 public static void main(String[] args) throws IOException {
  String str;
  TreeAppLL tree = new TreeAppLL(null);
  do {
   System.out.print("Enter the Tree Node, Enter 'Y' to exit: ");
   str = getInput();
   if (str.equalsIgnoreCase("y")) {
    break;
   }
   tree.insert(Integer.parseInt(str), Integer.parseInt(str));
   System.out.println("");
  } while (true);
//  tree.traversal();
  tree.displayTree();
 }

 public static String getInput() throws IOException {
  InputStreamReader inputStream = new InputStreamReader(System.in);
  BufferedReader reader = new BufferedReader(inputStream);
  String str = reader.readLine();
  return str;
 }
}



This requires a custom tree Node class which i created.


package com.test.ds;

public class TreeNodeLL {

 int key;
 int data;
 int leftSum;
 int rightSum;
 TreeNodeLL leftChild;
 TreeNodeLL rightChild;

 public TreeNodeLL(int key, int data) {
  this.key = key;
  this.data = data;
  this.leftChild = null;
  this.rightChild = null;
 }

}

I have also created a collection of common Tree problems which one should look at solving before moving  on with the topic.


package com.test.ds;


public class SumOfRootProb {

 public static void main(String[] args) {
  TreeNodeLL item = new TreeNodeLL(5, 10);
  TreeAppLL tree = new TreeAppLL(item);
  tree.insert(3, 20);
  tree.insert(7, 10);
  tree.insert(6, 10);
  tree.insert(2, 10);
  tree.insert(4, 10);
  tree.insert(9, 10);
  
  tree.displayTree();
  
  SumOfRootProb obj = new SumOfRootProb();
  obj.sum(tree.getRoot());
  
  tree.displayTree();
  
  System.out.println(obj.maxDepth(tree.getRoot()));
  
  System.out.println(obj.hasSumValue(tree.getRoot(), 18));
  
  obj.recPathPrint(tree.getRoot());
  

  TreeNodeLL item2 = new TreeNodeLL(5, 10);
  TreeAppLL tree2 = new TreeAppLL(item2);
  tree2.insert(3, 20);
  tree2.insert(7, 10);
  tree2.insert(6, 10);
  tree2.insert(2, 10);
  tree2.insert(4, 10);
  
  
  int result = obj.sameTree(tree.getRoot(), tree2.getRoot());
  if (result == 0) {
   System.out.println("Both with same structure");
  }
  else{
   System.out.println("Tum ho jhoote jhoote jhoote");
  }
  tree2.displayTree();
  tree.displayTree();
 }

 public int sum(TreeNodeLL node){
  if (node == null) {
   return 0;
  }
  else{
   node.leftSum = sum(node.leftChild);
   node.rightSum = sum(node.rightChild);
   return node.key + node.leftSum + node.rightSum;
  }
 }
 
 public int maxDepth(TreeNodeLL root) {
  int lDepth = 0, rDepth = 0;
  if(root == null){
   return 0;
  }
  lDepth = maxDepth(root.leftChild);
  rDepth = maxDepth(root.rightChild);
  if(lDepth > rDepth){
   return lDepth + 1;
  } else{
   return rDepth + 1;
  }
 }
 
 public boolean hasSumValue(TreeNodeLL node, int sum){
  if(node == null){
   return (sum == 0);
  }
  else{
   int subSum = sum - node.key;
   return (hasSumValue(node.leftChild, subSum)||hasSumValue(node.rightChild, subSum));
  }
  
 }
 public void recPathPrint(TreeNodeLL root){
  int[] path = new int[10];
  printPath(root, path, 0);
 }
 
 public void printPath(TreeNodeLL node, int[] path, int pathLen){
  if(node == null){
   return;
  }
  else{
   path[pathLen] = node.key;
   pathLen++;
   if(node.leftChild == null && node.rightChild == null){
    System.out.print("Path ");
    for(int i = 0; i< pathLen; i++){
     System.out.print(path[i] + " ");
    }
    System.out.println("");
   } else{
    printPath(node.leftChild, path, pathLen);
    printPath(node.rightChild, path, pathLen);
   }
  }
 }
 
 public void mirror(TreeNodeLL node){
  if(node == null){
   return;
  }
  else{
   TreeNodeLL temp;
   mirror(node.leftChild);
   mirror(node.rightChild);
   temp = node.leftChild;
   node.leftChild = node.rightChild;
   node.rightChild = temp;
  }
 }
 
 public void doubleTree(TreeNodeLL node){
  if(node == null){
   return;
  } else{
   doubleTree(node.leftChild);
   doubleTree(node.rightChild);
   TreeNodeLL newItem = new TreeNodeLL(node.key, node.data);
   newItem.leftChild = node.leftChild;
   node.leftChild = newItem;
  }
 }
 
 public int sameTree(TreeNodeLL root1, TreeNodeLL root2){
  if(root1 == null && root2 == null){
   return 0;
  } else if(root1 != null && root2 != null){
   int lResult = sameTree(root1.leftChild, root2.leftChild);
   int rResult = sameTree(root1.rightChild, root2.rightChild);
   if(lResult == 0 && rResult == 0){
    return 0;
   } else{
    return -1;
   }
   
  } else{
   return -1;
  }
 }
 
 public void longestPath(TreeNodeLL node, int[] path, int length, int maxLength){
  if(node == null){
   return;
  }
  else{
   path[length] = node.data;
   length++;
   if(node.leftChild == null && node.rightChild == null){
    if(maxLength < length){
     maxLength = length;
    }
   }
   else{
    longestPath(node.leftChild, path, length, maxLength);
    longestPath(node.rightChild, path, length, maxLength);
   }
  }
 }
} 

References:



Data Structures in Java by Robert Lafore

Euler's Problem 18

if you have heard of Euler's Problems then you might be aware of the Site Euler.net.

We have the input array

3
7 4
2 4 6
8 5 9 3

This problem deals with getting a path from top to bottom of contiguous elements which has the highest sum.

The trick is to see from the bottom up, in this example take the second last row and calculate the sum with one element being this and second being the element directly below and diagonally adjacent.

So, for element 2 in row 3  would be :
2 + 8 = 10
2+5 = 7

So, we can narrow down that we can choose the max number out of the two options which will give us more sum value.

Now, after calculating this sum replace the Sum value in this case 10 in position of 2.

Similarly, we will have this at the end of iteration for row = 2

3
7 4
10 13 15


Hence the solution is : 3 7 4 9
Sum : 23

Here is the Java code for the same


package com.test.practise;

public class MaxInMatrix {
 
 private int[][] input;
 private int[] output;
 
 public MaxInMatrix(int[][] input){
  this.input = input;
  this.output = new int[input.length];
 }
 
 
  public void getPath(){
  output[0] = input[0][0];
  int row = input.length -2;
  int j = 0;
  while(row >= 0){
   for(j=0; j<= row; j++){
    input[row][j] += Math.max(input[row+1][j], input[row+1][j+1]);
   }
   row--;
  }
  
  
  System.out.println(" ");
  System.out.print("Total Sum of the path is: " + input[0][0]);
 }
 
 
 public static void main(String[] args) {
  int[][] input = {{3},{7,4},{2,4,6},{8,5,9,3}};
  MaxInMatrix obj = new MaxInMatrix(input);
  obj.getPath();
 }

}


Refernces:
Euler's Project : http://projecteuler.net

Saturday, May 5, 2012

Making Oracle JAVA work on Ubuntu 12.04

With the suspension of support for more Ubuntu friendly format from Oracle we sometime face issues with installing Oracle Jdk 7 on ubuntu.
I have a 64 bit oracle JDK installed on my system from the following PPA
PPA: http://ppa.launchpad.net/webupd8team/java/ubuntu
you need to perform the following steps for installing the oracle JDK7 on your ubuntu 12.04 64 bit system
1. $> sudo add-apt-repository ppa:webupd8team/java
2. $> sudo apt-get update
3. $> sudo apt-get install oracle-java7-installer
After this you can check and select which java version you would like to use on the system
$>sudo update-alternatives --config java
Once this is done you probably would like to ensure that browser is using this java plugin, for that you need to carry out these options
create a "plugins" directory in the "~/.mozilla" path
$> mkdir ~/.mozilla/plugins 
Now you need to have a soft link to the actual file, which will be responsible for running the java on your browser(mozilla/chrome/chromium all use this plugins directory)   
$>ln -s /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libnpjp2.so ~/.mozilla/plugins
Once this is done you check the oracle link Test Page to see if the java is running fine on your system  
Now you would probably like to run eclipse on your system, for that these is a catch. I was facing issues when i was trying to open eclipse form my system and was getting this error
java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: 
no swt-gtk-3740 in java.library.path
no swt-gtk in java.library.path
What this means is that the .swt folder at your home directory is missing few files which you need to manually copy. First you need to have following packages installed(generally they are installed if you have Gnome 3) 
$> sudo apt-get install libswt-gtk-3-jni libswt-gtk-3-java
Once you have installed these packages you can proceed to copy files which are needed
$> sudo cp /usr/lib/jni/libswt-*3740.so ~/.swt/lib/linux/x86_64
In case its a i386 install then the command will be 
$> sudo cp /usr/lib/jni/libswt-*3740.so ~/.swt/lib/linux/x86
You could also create the soft link to required files 
libswt-atk-gtk-3740.so -> /usr/lib/jni/libswt-atk-gtk-3740.so
libswt-cairo-gtk-3740.so -> /usr/lib/jni/libswt-cairo-gtk-3740.so
libswt-awt-gtk-3740.so -> /usr/lib/jni/libswt-awt-gtk-3740.so
libswt-gnome-gtk-3740.so -> /usr/lib/jni/libswt-gnome-gtk-3740.so
libswt-glx-gtk-3740.so -> /usr/lib/jni/libswt-glx-gtk-3740.so
libswt-gtk-3740.so -> /usr/lib/jni/libswt-gtk-3740.so
libswt-webkit-gtk-3740.so -> /usr/lib/jni/libswt-webkit-gtk-3740.so
libswt-pi-gtk-3740.so -> /usr/lib/jni/libswt-pi-gtk-3740.so
Once this is done you need to edit the eclipse.ini file to explicitly tell eclipse which VM to use. If you have installed eclipse using the Ubuntu Software Center you need to go to the following path to edit the file
$> sudo gedit /usr/lib/eclipse/eclipse.ini
You can specify the VM by adding these lines in the file
-vm
/usr/lib/jvm/java-7-oracle/bin

Once all these steps are done you should be ready with starting your development in Java on Ubuntu  12.04 64bit.

Enjoy !

References :

askubuntu.com   : http://askubuntu.com/questions/125150/unsatisfied-link-error-and-missing-so-files-when-starting-eclipse
technonstop.com    : http://technonstop.com/install-java-plugin-ubuntu-linux 
Stackoverflow.com    : http://stackoverflow.com/questions/10165693/ubuntu-eclipse-cannot-load-swt-libraries-not-opening