Saturday, February 16, 2013

A Beginner's Guide for Learning Java Spring MVC Framework - Part 3


In our last article, we have learned some Java Spring MVC basic concepts and investigated the Java source code from the sample project. Also, two exercises are provided at the end of the article to extend the functionality of the sample project. In this article, we will continue to extend the sample project to include unit test code for the Java code we have written. Unit testing is very important in software development. It allows developers to check the quality of the code. It is a good practice to write unit tests for all the Java classes created in your project. In the test-driven development(TDD) process, developers are even required to write unit tests before writing the actual code.

Unit Test with JUnit


JUnit is widely used as a testing framework for Java code. It is integrated into our implementation IDE, Spring Suite Tools. The sample project also already contains test folders src/test/java and src/test/resources. We can just add files under them. The following steps show how to add a unit test for the controller class HomeController.

Right click the package name under src/test/java, and choose New -> JUnit Test Case. In the pop-up dialog, fill in the test name as HomeControllerTest, check all the method stubs you like to create and select the class under test by click Browse... button. The class we are going to test is com.mycompany.hello.HomeController.



Check the home method to test in the next dialog, and click Finish button.



A skeleton code is automatically generated. In this test file, every method has an annotation before it (a new feature for JUnit 4.x). You can read the following JUnit tutorial  for the detailed information about these annotations. Since our code is pretty simple, we only need to implement the “real” test method, testHome.

In this test method, we first create the HomeController object, then create two objects for the input parameters, locale and model. The model object is an instance of ExtendedModelMap which implements the Model interface. After we call the home method, we test whether the return string is “home” and the model object is modified correctly.

public void testHome() {
            HomeController controller = new HomeController();
            Locale locale = new Locale("en");
            ExtendedModelMap model = new ExtendedModelMap();
            String view = controller.home(locale, model);
            assertEquals(view, "home");
            assertEquals(model.size(), 1);
            assertTrue(model.containsAttribute("serverTime"));
      }

After the code is finished, right click HoemControllerTest.java and select Run As -> JUnit Test. Spring Tool Suite will then run the unit test and show the test results.

Code Coverage

We use unit tests to check the quality of the code. How can we check the quality of the unit test code? One way to measure the quality of the unit tests is to use code coverage, which measures the percentage of the source code that is tested by the unit tests.

We use EclEmma as our code coverage tool. To install EclEmma, open the Help -> Eclipse Marketplace… dialog, and search for EclEmma. In the search results, select EclEmma and then follow the instructions to install it. After the installation, open Window->Customize Perspective… dialog and enable Java Code Coverage in the Command Groups Availability tab.



After we finish adding the code coverage into our IDE, a new code coverage button  is added in the main toolbar.

EclEmma uses a metric called branch coverage to measure the coverage percentage. In general, in order to have a 100% branch coverage on a function, your unit test code must test every statement of the function, and both true and false cases of every conditional statement, such as if, switch, while, ? operator.

To run the unit test with code coverage, you can simply click the “Coverage Run” toolbar button. After the unit test is finished, you can see the results in the “Coverage” tab under the source code editor window. Also the results are intuitively shown in the source code editor window by highlighting code lines with different colors. In default, EclEmma uses green, red, and yellow to indicate different coverage states: fully covered, not covered, and partially covered respectively. A partially covered code line is normally due to the missing of branches. For example, only the true case of an if statement is tested, but the false case is not tested.



Exercise
Write unit tests for the code you added in the previous exercises. Try to get 100% code coverage for your unit test code.

Saturday, February 9, 2013

A Beginner's Guide for Learning Java Spring MVC Framework - Part 2


In a previous article, we have learned to set up a development environment to write Java Spring code, and created our first Spring MVC project. In this article, we will first introduce some basic concepts of Java Spring MVC, and take a detailed look at the sample project.

1. Java Spring MVC Basics
In Java Spring MVC framework, MVC stands for Model, View, and Control. A model can be treated as an object that contains a bunch of data. The data can come from anywhere, such as a back-end database, web server configurations, etc. A view can be treated as an object that reflects the model. For example, we can use a Java Server Page (JSP) to generate an HTML page based on the model. A controller works between the model and view. It can put necessary data into the model and then select a view to reflect the model. A typical work flow of Java Spring MVC is described as follows:
  • Receive a web request a client, and resolve the request's information, such as relative path (e.g. /help), request method (e.g. GET).
  • Use a servlet called DispatcherServlet to find a controller that is responsible for handling this request based on the resolved information.
  • The controller prepares the model, and then tells Java Spring MVC which view should be used to reflect the model.
  • Find the view to render the response based on the model and send back the response to the client.
There are many other technical terms for Java Spring MVC and the general Java Spring framework. A good place to learn these terms is the Wikipedia page for Java Spring and Spring Framework Reference Documentation. As a beginner, you don't need to learn more details about these terms. You can just think Java Spring MVC is a magic box. All you need to do is to write a controller and a view together working with a model for each web request URL, and Java Spring MVC will handle all the rest stuff.

2. An Overview of the Sample Project.
There are four important files in this sample projects: web.xml, servlet-context.xml, HomeController.java, and home.jsp.






web.xml

This file is called Web Application Deployment Descriptor. It provides configuration information to the web server to run your web application. For example, in the sample project, the web.xml defines a servlet with name appServlet (in the <servlet> tag), whose detailed information is defined in the file servlet-contex.xml. Also it tells the web server that appServlet should be invoked for the request on the root URL (in the <servlet-mapping> tag).

<servlet>
   <servlet-name>appServlet</servlet-name>
   <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring/appServlet/servlet-context.xml
      </param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
   <servlet-name>appServlet</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>



servlet-context.xml

This file provides detailed information of appServlet defined in the web.xml. In the sample project, it has a Java bean object which is used to resolve the view names selected by controllers. If a controller return a view name, it will put the prefix string before the view name and put the suffix after the view name to make a string that indicate the complete path of the view file. For example, if a controller returns a view name “home”, it will resolve it to “/WEB-INF/views/home.jsp”.

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

  <beans:property name="prefix" value="/WEB-INF/views/" />
  <beans:property name="suffix" value=".jsp" />
</beans:bean>

HomeController.java

This file contains a controller class called HomeController. This file can be treated as a template to write Java Spring MVC controller classes. It uses an important technology called Spring Annotation. An annotation can be put before a class or method to describe properties of the class or method. It is started with the character @, e.g. @Controller, @RequestMapping, etc.

There are two annotations in this file. Before the class definition, there is an annotation @Controller. This annotation defines that this class is a Controller class. Before the home function, there is an annotation @RequestMapping(value = "/", method = RequestMethod.GET). This annotation defines that the home method is responsible for handling the HTTP GET request of the root “/” URL.

The home method has two input parameters, locale and model. You can put more parameters in this method if you need them. Please read Spring Framework Reference on what kind of parameters you can put in the handler method.

The home method uses a logger to log the locale information and put the current date into the model, then returns the view name “home”. From the configuration in the servlet-context.xml, Java Spring MVC will resolve the view to the file “/WEB-INF/views/home.jsp. The method can also return other types of object. Please read Spring Framework Reference for the possible return types.

This is another “magic” of Java Spring MVC. You can put a bunch of input parameters in the handler method, and return different types of objects. Java Spring MVC can resolve them “magically” when the method is called.

@Controller

public class HomeController {
     
      private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
     
      /**
       * Simply selects the home view to render by returning its name.
       */
      @RequestMapping(value = "/", method = RequestMethod.GET)
      public String home(Locale locale, Model model) {
            logger.info("Welcome home! The client locale is {}.", locale);
           
            Date date = new Date();
            DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
           
            String formattedDate = dateFormat.format(date);
           
            model.addAttribute("serverTime", formattedDate );
           
            return "home";
      }
}

home.jsp

This file is the view part of the sample project. It contains a variable ${serverTime}, which is defined in the model passed from the controller.


3. Exercises

Now you should see that how easy it is to implement in Java Spring MVC framework. Let's do some exercises to expand the basic sample projects. I will leave them to you to start writing your own Java Spring MVC code.

3.1. Extend HomeController method to check the client's locale information, and in the home view,   display "Your language is English" if the locale language is English, or "Your language is not English" otherwise .
3.2. Create a new controller which can handle GET request on the /browserinfo url, In the view of the controller, it displays the client's web browser information, such as browser type (IE, Firefox, Chrome, Safari, etc) and version.



Friday, February 1, 2013

A Beginner's Guide for Learning Java Spring MVC Framework

This tutorial is for the programmers who have little knowledge of Java Spring MVC framework and want to learn this technology from scratch. It shows you how to write Java Spring code from the very beginning.

1.Installation
First, you need to install necessary software to start writing code in Java Spring. You need an IDE to write Java code, a JDK to build your Java code, and a web server to run your code. Also you need a database if your code have database operations. Since Java is a cross platform programming language, you can work under different platforms. In the following, we are using Windows as our development environment.

1.1. JDK
Get the latest Java Platform (JDK) from Oracle (http://www.oracle.com/technetwork/java/javase/downloads/index.html) and install it. After the installation, set JAVA_HOME system environment variable to the JDK installation path.

1.2. Web server (Apache Tomcat)
We use Apache Tomcat as the web server to run our Java Spring code. You can get the latest Apache Tomcat from Apache (http://tomcat.apache.org/) and extract it to a folder. To have a smoke test on the web server, go to the bin folder of the Apache Tomcat installation folder and run startup.bat. Then open a web browser and test the web address http://localhost:8080 to see if you can see the homepage.

1.3. IDE (Spring Tool Suite)
Get the latest Spring Tool Suites from SpringSource (http://www.springsource.org/sts) and install it. The first time you run the Spring Tool Suite, it will ask you to select a workspace. You can input a folder as your workspace and set this folder as the default workspace. In the welcome screen, click Open Dashboard button, and you can start using this nice IDE.


1.4. Database
We can first start development without a database. We will discuss database options in the future articles.

2. Add Apache Tomcat server to Spring Tool Suite
You can run your Java Spring code directly on the web server in the Spring Tool Suite. To achieve that, you first need to add the web server into Spring Tool Suite.

  • Right click Servers, and select New -> Others in the context menu. In the pop-up dialog, choose Server and click Next button.
  • Choose the Tomcat server name that matches installed version of our web server, e.g. Apache -> Tomcat v7.0 Server, and click Next button.
  • Input the Tomcat installation directory, e.g. C:\apache-tomcat-7.0.35, and click Next button.
  • In the resources dialog, you can select the project you want to run on the server. Since we don't have any project in the workspace currently, you can click Finish button to finish the process.
  • Expand the Servers category in the Package Explorer tab, you can see that there is a new server, Tomcat v7.0 Server at localhost-config, added under this category. Also the Apache Tomcat server is listed in the Servers tab.

3. Run a sample Spring MVC project in Spring Tool Suite
Spring Tool Suite provides a template Spring MVC project for programmers to start with. To open the template project, go to File -> New -> Spring Template Project, and select Spring MVC Project in the pop-up dialog.
In the Project Settings dialog, input the project name and the top-level package name, and click Finish button.


A new project is created and shown in the Package Explorer tab. This template project was configured to build upon JRE 6. If you have a newer version of JRE installed, like what we have with JRE 7, there will be a build error (Can not find the tag library descriptor for “http://java.sun.com/jsp/jstl/core”) and warning (Build path specifies execution environment JavaSE-1.6...) after the project is automatically built.


To fix this problem, right click the project name, and choose the Properties. In the properties dialog, select Java Build Path. In Libraries tab, remove JRE System Library [JavaSE-1.6]. Then click Add Library... button and add JRE System Library. See the following figure on what the project’s Java Build Path should be.



To run the project, right click the project name, Select Run As -> Run on Server. In the Run On Server dialog, choose the Tomcat server we created previously.


After you click Finish button, you now have a Java Spring MVC Hello World application running on your Tomcat web server!



In default, the Hello World application is deployed into the Tomcat web server under the project folder, i.e. $ProjectFolder\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps. You can right click the Tomcat server name under Servers tab, and select Browse Deployment Location...  to see the deployment directory.


To deploy the whole web application into our installed Tomcat server, we need to first export the web application into a WAR file, and then deploy the WAR file into the Tomcat server.
  • Right click the Hello project name in the Package Explorer tab, and select Export...
  • In the Export dialog, choose web -> WAR file, and click Next button



  • Input the web project name and destination (put the file into the webapps folder of the Tomcat installation folder) . You can also check the Optimize for Apache Tomcat v 7.0 option.

  •  Restart the Tomcat web server and the WAR file should be automatically deployed into the Hello folder. You can visit http://localhost:8080/Hello/ to test the deployment.



4. Summary
In this tutorial, we set up an implementation environment for Java Spring and run a sample Java Spring MVC project on the implementation environment. In the next tutorial, we will introduce some basic concepts of Java Spring MVC framework by analyzing this Hello World sample project and make some changes on the project.

Sunday, January 6, 2013

Draw a Line with the Exact Real-world Length on Screen



Introduction

I played an educational game which teaches kids how to use a ruler to draw and measure a straight line. However, the unit length of the ruler widget on the computer does not equal to the actual length in the real world. For example, if you use the ruler widget to draw a 2 cm line, and then use a real ruler to measure it on the screen, the length is normally much greater than 2 cm. Although the game is for educational purpose and it is acceptable not to strictly follow the real length, it would be better if we can provide some ruler widget that has the same unit length with the real world ruler. Therefore, the problem we are trying to solve in this article is: Draw a  line with length of 1 centimeter on the computer screen, regardless of the screen’s physical size and  configurations, such as resolutions, orientation, etc.
  

Solution

The math part of the solution is pretty simple. Suppose the screen resolution is 1680×1024 and the computer screen’s physical size is 47cm×30cm (a typical 22-inch display), then horizontally, there are 1680/47 pixels per centimeter. Therefore, to draw a 1 cm line horizontally, we can just draw a line with 1680/47 pixels. The following is a C# code for the drawing part.

//Draw a horizontal line on the graphics g with color clr.
//The starting coordinate of the line defined in x, y.
//The length (in cm) of the line is defined in length.
//The screen's horizontal resolution (in pixels) is defined in horizoantalResolution
//The screen's physical width (in cm) is defined in screenWidth.
private void DrawHorizontalLine(Graphics g, Color clr, int x, int y, float length, int horizoantalResolution, int screenWidth)
{
   float pixelpercm = (float)horizoantalResolution / screenWidth;
   g.DrawLine(new Pen(new SolidBrush(clr), 1), x, y, x + length * pixelpercm, y);
}

It is easy to get the screen resolution in C#. The following code can get the resolution of the primary screen (a computer can connect to multiple screens).

int w = Screen.AllScreens[0].Bounds.Width;
int h = Screen.AllScreens[0].Bounds.Height;

It is a little bit hard to get the physical size of the computer screen. One technology we can use is to read the extended display identification data (EDID) of a connected display. The data structure of EDID can be found in the following Wikipedia page: http://en.wikipedia.org/wiki/Extended_display_identification_data . The display physical width and height are defined in the bytes 21 and 22 of EDID.

In Windows, the EDID are stored in the system registry under [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\$DISPLAY_NAME\$DISPLAY_ID\Device Parameters], where $DISPLAY_NAME and $DISPLAY_ID are display specific strings. The following C# code example shows how to read the EDID from the registry and extract the physical size of the display from EDID. Note that there may exists more than one EDID entries if the computer has multiple displays connected. Also, we can read other display properties, such as model name, from EDID. Please refer to  http://en.wikipedia.org/wiki/Extended_display_identification_data on data format of EDID.

private void GetDisplays()
{
   RegistryKey key = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY");
   if (key == null)
      return;
   //sName is the display name
      foreach (string sName in key.GetSubKeyNames()) 
  { 
      if (sName == "Default_Monitor") 
         continue;
       RegistryKey keyDisplay = key.OpenSubKey(sName);
      //sDisplayID is the display ID
              foreach (string sDisplayID in keyDisplay.GetSubKeyNames())
      {
         RegistryKey keyDevice = keyDisplay.OpenSubKey(sDisplayID);
         if (keyDevice == null)
            continue;
         //sDriver is the display driver name
                    string  sDriver = (string)keyDevice.GetValue("Driver");
         RegistryKey keyParameter = keyDevice.OpenSubKey("Device Parameters");
         if (keyParameter == null)
         { 
            keyDevice.Close();
            continue;
         }
         byte[] EDID = (byte[])keyParameter.GetValue("EDID");
         keyParameter.Close();
         keyDevice.Close();
         if (EDID == null)
            continue;
         //Display's physical height and width
         int width = EDID[21];
         int height = EDID[22];
     }
     keyDisplay.Close();
   }
   key.Close();
}

Now we have enough information to draw a line, the screen resolution and the physical size of the screen. We can feed these parameters to the DrawHorizontalLine function.  Also it is not hard to extend the above horizontal solution to the vertical case or to the line with any slope.
   

Future Works 

  • The above solution is for Windows only. For other platforms, such as Mac, Linux, it should be pretty easy to get current screen's resolution. However, we need to do some more research on where EDID are stored in these platforms.
  • If the computer has multiple connected displays, we need extra code to determine in which display current application is running and then use the corresponding width and height parameters.
  • This solution is also useful for a new "Print Preview" feature, which can produce the preview exactly the same as what will be printed. Imagine the computer shows an A4 paper on the screen with the exact width and height as a real A4 paper, and all the content displayed on the paper has the same size as the content printed on a real A4 paper.

Tuesday, January 1, 2013

C++ Code for Some Binary Tree Algorithms

The following C++ code contains several algorithms for binary tree operations.
  • Preorder tree traversal: recursive method; iterative method by using stack data structure; iterative method without stack, but by using a parent node in each tree node.
  • Inorder tree traversal: recursive method; iterative method by using stack data structure; iterative method without stack, but by using a parent node in each tree node.
  • Postorder tree traversal: recursive method; iterative method by using two stacks.
  • Depth first traversal: same as preorder tree traversal
  • Breadth first traversal: print the tree nodes level by level
  • Flattening traversal: flatten the binary tree to a singly linked list for traversal.
  • Encode/Decode a binary tree: Convert a binary tree to a formatted string or convert a formatted string to a binary tree.
  • Check if a binary tree is a binary search tree (BST)
  • Find the largest BST subtree of a binary tree
  • Binary search in a BST
  • Preorder search in a general binary tree
  • Find the lowest common ancestor (LCA) of two binary tree nodes
  • Build a binary tree from inorder and preorder traversal sequence

The tree structure definition is defined here (BinaryTree.h).



#pragma once
#include <string>
using namespace std;

typedef struct TreeNode
{
   TreeNode(int d)
   {
      data = d;
      left = NULL;
      right = NULL;
      parent = NULL;
   }
   int data;
   struct TreeNode *left;
   struct TreeNode *right;
   struct TreeNode *parent;
}
TreeNode;

class BinaryTree
{
public:
   BinaryTree();
   ~BinaryTree();
   void postorderRelease(TreeNode *node);

   void preorder();
   void inorder();
   void postorder();
   void depthFirst();
   void breadthFirst();
   void flatten();
   string encode();
   void decode(const string & s);
   bool isBST();
   TreeNode * binarySearch(int data);
   TreeNode * preorderSearch(TreeNode *node, int data);
   TreeNode * LCA(int data1, int data2);
   void buildFromInPreOrder(const vector<int> &inorder, const vector<int> &preorder);
private:
   void preorder(const TreeNode *node);
   void preorderIterative(const TreeNode *node);
   void preorderIterativeNoStack(const TreeNode *node);
   const TreeNode *preorderNext(const TreeNode *node);
   void inorder(const TreeNode *node);
   void inorderIterative(const TreeNode *node);
   void inorderIterativeNoStack(const TreeNode *node);
   const TreeNode *inorderNext(const TreeNode *node);
   void postorder(const TreeNode *node);
   void postorderIterative(const TreeNode *node);
   void preorderEncode(const TreeNode *node, string *encodeStr, vector<string> *data);
   TreeNode * preorderDecode(const string &encodeStr, const vector<int> &data, string::const_iterator &strItr, vector<int>::const_iterator &dataItr);
   bool isBST(const TreeNode *node, int *min, int *max);
   int BinaryTree::maxBST(TreeNode *node, int *min, int *max, TreeNode *&maxBSTRoot, int *maxBSTTotal);
   TreeNode * BSTLCA(int data1, int data2);
   TreeNode * LCA(TreeNode *rootNode, TreeNode *node1, TreeNode *node2);
   TreeNode * LCAIterative(TreeNode *rootNode, TreeNode *node1, TreeNode *node2);
   TreeNode * buildFromInPreOrder(const vector<int> &inorder, const vector<int> &preorder,
   int inorderStart, int inorderEnd, int preorderStart, int preorderEnd, map<int, int> &inorderMap);
private:
   TreeNode *root;
};
 

The source code is implemented here  (BinaryTree.cpp).



#include <iostream>
#include <sstream>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include "BinaryTree.h"

BinaryTree::BinaryTree()
{
   this->root = NULL;
}

BinaryTree::~BinaryTree()
{
   postorderRelease(root);
}

void BinaryTree::postorderRelease(TreeNode *node)
{
   if (node == NULL)
      return;
   postorderRelease(node->left);
   postorderRelease(node->right);
   delete node;
}

void BinaryTree::preorder()
{
   preorder(root);
   cout<<endl;
   preorderIterative(root);
   cout<<endl;
   preorderIterativeNoStack(root);
   cout<<endl;
}

void BinaryTree::inorder()
{
   inorder(root);
   cout<<endl;
   inorderIterative(root);
   cout<<endl;
   inorderIterativeNoStack(root);
   cout<<endl;
}

void BinaryTree::postorder()
{
   postorder(root);
   cout<<endl;
   postorderIterative(root);
   cout<<endl;
}

void BinaryTree::preorder(const TreeNode  *node)
{
   if (node == NULL)
      return;
   cout<<node->data<<" ";
    preorder(node->left);
    preorder(node->right);
}

void BinaryTree::inorder(const TreeNode  *node)
{
   if (node == NULL)
      return;
    inorder(node->left);
    cout<<node->data<<" ";
    inorder(node->right);
}

void BinaryTree::postorder(const TreeNode  *node)
{
   if (node == NULL)
      return;
    postorder(node->left);
    postorder(node->right);
    cout<<node->data<<" ";
}

void BinaryTree::preorderIterative(const TreeNode *node)
{
   if (node == NULL)
      return;
   stack<const TreeNode *> nodes;
   nodes.push(node);
   while (!nodes.empty())
   {
      const TreeNode *currentNode = nodes.top();
      cout<<currentNode->data<<" ";
      nodes.pop();
      if (currentNode->right)
         nodes.push(currentNode->right);
      if (currentNode->left)
         nodes.push(currentNode->left);
   }
}

//The next node of node X in the preorder sequence is:
// 1. X's left child if it is not NULL;
// 2. X's right child if it is not NULL;
// 3. The right child of the lowest ancester of node X whose left child is also the ancestor of node X and whose right child is not NULL.
// 4. NULL if we finished the search.
const TreeNode * BinaryTree::preorderNext(const TreeNode *node)
{
   if (node == NULL)
      return NULL;
   else if (node->left)
      return node->left;
   else if (node->right)
      return node->right;
   else
   {
      TreeNode *parent = node->parent;
      while (parent != NULL && (node == parent->right || parent->right == NULL))
      {
         node = parent;
         parent = parent->parent;
      }
      if (parent == NULL)
         return NULL;
      else
         return parent->right;
   }
}

//preorder traveral without using a stack. This method depends on the parent pointer
//of the tree node.
void BinaryTree::preorderIterativeNoStack(const TreeNode *node)
{
   while (node)
   {
      cout<<node->data<<" ";
      node = preorderNext(node);
   }
}

void BinaryTree::inorderIterative(const TreeNode *node)
{
   if (node == NULL)
      return;
   stack<const TreeNode *> nodes;
   const TreeNode *currentNode = node;
   while (true)
   {
      if (currentNode)
      {
         nodes.push(currentNode);
         currentNode = currentNode->left;
      }
      else
      {
         if (!nodes.empty())
         {
            currentNode = nodes.top();
            cout<<currentNode->data<<" ";
            nodes.pop();
            currentNode = currentNode->right;
         }
         else
         {
            return;
         }
      }
   }
}

//inorder traveral without using a stack. This method depends on the parent pointer
//of the tree node.
void BinaryTree::inorderIterativeNoStack(const TreeNode *node)
{
   if (node == NULL)
      return;
   while(node->left)
   {
      node = node->left;
   }
   while (node)
   {
      cout<<node->data<<" ";
      node = inorderNext(node);
   }
}

//The next node of node X in the inorder sequence is:
// 1. The left most node of X's right sub tree if X's right child is not NULL;
// 2. the lowest ancester of node X whose left child is also the ancestor of node X.
// 3. NULL if we finished the search.
const TreeNode * BinaryTree::inorderNext(const TreeNode *node)
{
   if (node == NULL)
      return NULL;
   else if (node->right)
   {
      node = node->right;
      while(node->left)
      {
         node = node->left;
      }
      return node;
   }
   else
   {
      TreeNode *parent = node->parent;
      while (parent != NULL && node != parent->left)
      {
         node = parent;
         parent = parent->parent;
      }
      return parent;
   }
}

void BinaryTree::postorderIterative(const TreeNode *node)
{
   if (node == NULL)
      return;
   stack<const TreeNode *> nodes;
   stack<const TreeNode *> outputs;
   nodes.push(node);
   while (!nodes.empty())
   {
      const TreeNode *currentNode = nodes.top();
      outputs.push(currentNode);
      nodes.pop();
      //push left children first
      if (currentNode->left)
         nodes.push(currentNode->left);
      if (currentNode->right)
         nodes.push(currentNode->right);
   }
   while (!outputs.empty())
   {
      cout<<outputs.top()->data<<" ";
      outputs.pop();
   }
}


void BinaryTree::depthFirst()
{
   //preorder is the same as the depthFirst search in graph
   preorder(root);
   cout<<endl;
}

//breadth first traveral, print the nodes level by level
void BinaryTree::breadthFirst()
{
   queue<TreeNode*> queue;
   queue.push(root);
   while (!queue.empty())
   {
      TreeNode *node = queue.front();
      cout<<node->data<<" ";
      queue.pop();
      if (node->left)
         queue.push(node->left);
      if (node->right)
         queue.push(node->right);
   }
   cout<<endl;
}

void BinaryTree::flatten()
{
    TreeNode *tail = root;
    while (tail->left)
   {
        tail=tail->left;
   }
   vector<TreeNode*> tails;
   tails.push_back(tail);
    TreeNode *node = root;
    while(node)
    {
      cout<<node->data<<" ";
        if (node->right)
      {
            tail->left = node->right;
            while(tail->left)
                tail=tail->left;
         tails.push_back(tail);
       }
        node=node->left;
    }
    //restore
    for (unsigned int i = 0; i < tails.size(); i++)
        tails[i]->left = NULL;
   cout<<endl;
}

//encode the binary tree to a string. We use "\n" as delimiter.
string BinaryTree::encode()
{
   vector<string> data;
   string encodeStr = "";
   preorderEncode(root, &encodeStr, &data);
   encodeStr += "\n";
   for (vector<string>::const_iterator itr = data.begin(); itr != data.end(); itr++)
   {
      encodeStr += *itr;
      encodeStr += "\n";
   }
   return encodeStr;
}

//use preorder traversal to encode the binary tree.
//We put extra "dummy" NULL nodes to each tree node so that the tree is a "complete" tree,
//i.e., each tree node has exactly two children (either a "real" tree node or a "dummy" node)
//In the encode string, if it is a tree node, the bit is set to 1,
//if it is a dummy NULL node (e.g. a leaf node has two dummy NULL child nodes), the bit is set to 0.
//Therefore, if the tree has n nodes, then we need 2n+1 bits to encode.
//data vector stores the node data in a preorder sequence.
//we use bit string to encode, i.e. "1110000". It is possible to use int array for a more compact storage.
void BinaryTree::preorderEncode(const TreeNode *node, string *encodeStr, vector<string> *data)
{
   if (data == NULL || encodeStr == NULL)
      throw std::exception();
   if (node == NULL)
   {
      *encodeStr += "0";
      return;
   }
   *encodeStr += "1";
   ostringstream convert; //convert int to string.
   convert<<node->data;
   data->push_back(convert.str());
   preorderEncode(node->left, encodeStr, data);
   preorderEncode(node->right, encodeStr, data);
}

void BinaryTree::decode(const string& s)
{
   vector<int> data;
   string encodeStr = "";
   unsigned int index = 0;
   string currentStr = "";
   while (index < s.length())
   {
      if (s[index]=='\n')
      {
         if (encodeStr.length() > 0)
         {
            int value = atoi(currentStr.c_str());
            data.push_back(value);
         }
         else
         {
            encodeStr = currentStr;
         }
         currentStr = "";
      }
      else
      {
         currentStr += s[index];
      }
      index++;
   }
   string::const_iterator strItr= encodeStr.begin();
   vector<int>::const_iterator dataItr = data.begin();
   root = preorderDecode(encodeStr, data, strItr, dataItr);
}

TreeNode * BinaryTree::preorderDecode(const string &encodeStr, const vector<int> &data, string::const_iterator &strItr, vector<int>::const_iterator &dataItr)
{
   if (strItr == encodeStr.end())
      throw std::exception();
   if (*strItr == '0')
   {
      strItr++;
      return NULL;
   }
   if (dataItr == data.end())
      throw std::exception();
   TreeNode *node = new TreeNode(*dataItr);
   dataItr++;
   strItr++;
   node->left = preorderDecode(encodeStr, data, strItr, dataItr);
   node->right = preorderDecode(encodeStr, data, strItr, dataItr);
   if (node->left)
      node->left->parent = node;
   if (node->right)
      node->right->parent = node;
   return node;
}

//check if a binary tree is a binary search tree (BST).
//for every node of a binary tree, if it satisfies:
//the max of its left sub tree <= node->data <= the min of its right sub tree.
//then it is a BST.
bool BinaryTree::isBST()
{
   int min, max;
   bool r = isBST(root, &min, &max);
   cout<<"min="<<min<<" max="<<max<<endl;

   TreeNode *maxBSTRoot = NULL;
   int maxBSTTotal = 0;
   int total = maxBST(root, &min, &max, maxBSTRoot, &maxBSTTotal);
   cout<<"min="<<min<<" max="<<max<<" total="<<maxBSTTotal<<" max BST root: "<<maxBSTRoot->data<<endl;

   return r;
}

bool BinaryTree::isBST(const TreeNode *node, int *min, int *max)
{
   if (node == NULL || min == NULL || max == NULL)
      return false;
   int leftMin = node->data;
   int leftMax = node->data;
   int rightMin = node->data;
   int rightMax = node->data;
   bool left = true;
   bool right = true;
   if (node->left)
      left = isBST(node->left, &leftMin, &leftMax);
   if (node->right)
      right = isBST(node->right, &rightMin, &rightMax);
   bool self = (leftMax <= node->data) && (node->data <= rightMin);
   *min = leftMin;
   *max = rightMax;
   return left && right && self;
}

//Find the largest subtree which is a BST.
//largest: the tree with largest number of nodes
//subtree: a part of the original tree whose leaf set is a subset of the original tree's leaf set.
int BinaryTree::maxBST(TreeNode *node, int *min, int *max, TreeNode *&maxBSTRoot, int *maxBSTTotal)
{
   if (node == NULL || min == NULL || max == NULL)
      return -1;
   int leftMin = node->data;
   int leftMax = node->data;
   int rightMin = node->data;
   int rightMax = node->data;
   int left = 0;
   int right = 0;
   if (node->left)
      left = maxBST(node->left, &leftMin, &leftMax, maxBSTRoot, maxBSTTotal);
   if (node->right)
      right = maxBST(node->right, &rightMin, &rightMax, maxBSTRoot, maxBSTTotal);
   bool self = (leftMax <= node->data) && (node->data <= rightMin);
   *min = leftMin;
   *max = rightMax;
   if (left >= 0 && right >= 0 && self)
   {
      int total = left + right + 1;
      if (total > *maxBSTTotal)
      {
         *maxBSTTotal = total;
         maxBSTRoot = node;
      }
      return total;
   }
   else
      return -1;
  
}

TreeNode * BinaryTree::binarySearch(int data)
{
   TreeNode *node = root;
   while (node)
   {
      if (node->data == data)
         break;
      else if (node->data > data)
         node = node->left;
      else
         node = node->right;
   }
   return node;
}

TreeNode * BinaryTree::preorderSearch(TreeNode *node, int data)
{
   if (node == NULL)
      return NULL;
   if (node->data == data)
      return node;
    TreeNode *left = preorderSearch(node->left, data);
   if (left)
      return left;
    TreeNode *right = preorderSearch(node->right, data);
   if (right)
      return right;
   return NULL;
}

TreeNode * BinaryTree::LCA(int data1, int data2)
{
   TreeNode* node = BSTLCA(data1, data2);
   cout<<node->data<<" ";
   return node;
}

//find the least common ancester(LCA) of two nodes in BST.
//the input parameters are two numbers.
//we assume the data in each tree node is unique.
TreeNode * BinaryTree::BSTLCA(int data1, int data2)
{
   TreeNode *node = root;
   while (node)
   {
      if (node->data >= data1 && node->data <= data2)
         break;
      else if (node->data > data2)
         node = node->left;
      else
         node = node->right;
   }
   return node;
}

//find the LCA of two nodes in a general binary tree.
//use bottom up approach.
TreeNode * BinaryTree::LCA(TreeNode *rootNode, TreeNode *node1, TreeNode *node2)
{
   if (rootNode == NULL) return NULL;
   if (rootNode == node1 || rootNode == node2)
      return rootNode;
   TreeNode *left = LCA(rootNode->left, node1, node2);
   TreeNode *right = LCA(rootNode->right, node1, node2);
   if (left && right)
      return rootNode;
   else if (left)
      return left;
   else
      return right;
}

//find the LCA of two nodes in a general binary tree.
//we assume the parent link exists in each tree node.
//________
//        \_________
//________/
//
TreeNode * BinaryTree::LCAIterative(TreeNode *rootNode, TreeNode *node1, TreeNode *node2)
{
   if (rootNode == NULL || node1 == NULL || node2 == NULL)
      return NULL;
   int count1 = 0;
   TreeNode *parent1 = node1;
   while (parent1 && parent1 != rootNode)
   {
      count1++;
      parent1 = parent1->parent;
   }
   int count2 = 0;
   TreeNode *parent2 = node2;
   while (parent2 && parent2 != rootNode)
   {
      count2++;
      parent2 = parent2->parent;
   }
   int offset = 0;
   parent1 = node1;
   parent2 = node2;
   if (count1 > count2)
   {
      offset = count1 - count2;
      while (offset > 0)
      {
         offset--;
         parent1 = parent1->parent;
      }
   }
   else
   {
      offset = count2 - count1;
      while (offset > 0)
      {
         offset--;
         parent2 = parent2->parent;
      }
   }
   while(parent1 != parent2 && parent1 && parent2)
   {
      parent1 = parent1->parent;
      parent2 = parent2->parent;
   }
   if (parent1 == NULL || parent2 == NULL)
      return NULL;
   else
      return parent1;
}
void BinaryTree::buildFromInPreOrder(const vector<int> &inorder, const vector<int> &preorder)
{
   map<int, int> inorderMap;
   for (unsigned int i = 0; i < inorder.size(); i++)
   {
      inorderMap[inorder[i]] = i;
   }
  root = buildFromInPreOrder(inorder, preorder, 0, inorder.size() - 1, 0, preorder.size() - 1, inorderMap);
}

TreeNode * BinaryTree::buildFromInPreOrder(const vector<int> &inorder, const vector<int> &preorder,
   int inorderStart, int inorderEnd, int preorderStart, int preorderEnd, map<int, int> &inorderMap)
{
   if (inorderStart > inorderEnd || preorderStart > preorderEnd)
   {
      return NULL;
   }
   int data = preorder[preorderStart];
   TreeNode *node = new TreeNode(data);
   int index = inorderMap[data];
   TreeNode *leftNode = buildFromInPreOrder(inorder, preorder, inorderStart, index - 1,
      preorderStart+1, preorderStart + (index - inorderStart), inorderMap);
   node->left = leftNode;
   if (leftNode)
      leftNode->parent = node;
   TreeNode *rightNode = buildFromInPreOrder(inorder, preorder, index + 1, inorderEnd,
      preorderStart + (index - inorderStart)+ 1, preorderEnd, inorderMap);
   node->right = rightNode;
   if (rightNode)
      rightNode->parent = node;
   return node;
}