Reading Time: 2 minutes


Stack is a very usable data structure that brings the LIFO setting into the game. Let’s elaborate LIFO; LIFO is the abbreviation of Last-In-First-Out. What does LIFO really mean for us? The intentions may vary and one of them is to have a pile of things stacked down to the bottom and take one from the top. Let’s apprehend the below illustration:

Yes, we understood it well. In the LIFO setting we insert towards bottom and and take from the top.

Sample Stack Usage Areas

  • In text editors “Undo” operations while we intend to revert an unwanted entry,
  • Browsers’ back buttons; make use of a similar way to be able to navigate to the earlier pages,
  • Recursive methods also utilize stack very well; starting from the first call till the last, all of the method executions are added on top of each other.


In the internally Stack can implement Singly Linked List or Array. Eventually the Time Complexity of the operations will slightly differ. In this stackoverflow Article, there are more insights and argument about the implementations. In my own implementation I preferred to use the Singly Linked List implementation.

Complexity of Stack

Since the internals of implementations differ for each variation; Singly Linked List and Array, the operations can differ. The given table is suitable for Singly Linked List implementation;

image courtesy of

Operations on Stack

Stack has three vital operations that we need to cover up. In some other languages and Stack implementations definitely have other additional operations like Java’s Stack implementation. However, these below operations are fundamental properties of the Stack data structure:

  • push: pushes the element on top of stack
  • pop: pops the element from the top and returns popped the value
  • peek: returns the head data but doesn’t delete it, takes a peek at it.


The code can be also found in my Github Repository @ to see how the code works, you can also check its Unit Test.

Shell Sort

Reading Time: < 1 minute


Shell Sort is a variation of the Insertion Sort. Shell Sort is very fast algorithm that is compact in code size. A gap in other words a distance is set that will be used between the elements in the array
Sub lists are made out of the elements in the gap and the sub lists are compared. In the comparison lower element goes to the left and greater is on the right.
The process continues, later on the gap gets smaller until it becomes one. After the gap reaches to one, then the Insertion Sort is applied to sort the rest. Depending of this gap the time complexity of the algorithm varies.


The code can be also found in my Github Repository @

Insertion Sort

Reading Time: < 1 minute


The 1st element is assumed to be sorted and the iteration starts from the second element towards the end. The difference in this algorithm compared to Bubble Sort,
it compares the element that are on the left of it. It all means that the sorting goes not forward, but backwards from the right to the left.
This algorithm is sufficient on smaller data sets like Bubble Sort, because its Time complexity is  O(n2).
In the implementations of the Insertion Sort only space complexity changes;
*. Imperative: O(1)
*. Recursive: O(n) because of the stacks that are created
The both imperative and the recursive versions are very similar, except in the recursive version, the comparison will start when the i is in second elements index which is 2


The code can be also found in my Github Repository @

Merge Sort

Reading Time: 2 minutes


Merge sort yet another sorting algorithm that benefits from the divide-and-conquer principle.  The main goal in this algorithm is to split the given array into individuals and merge them back during the course of the comparison.
Merge Sort seems kind of similar to the Merge sort, in the Comparison below you can study the differences and similarities. However, there is one challenge as I see in this algorithm is the merge. I find this part very complex, but besides its very easy to apprehend the algorithm.

Complexity Analysis

Time Complexity

  1. Best Case: O(n log n),
  2. Average Case: O(n log n),
  3. Worse Case: O(n log n)

Space Complexity


Comparison to Quick Sort

In general terms, the Merge Sort is often compared to the Quick Sort. In some sense, they tend to act similarly as they inherit the same divide-and-conquer principle, to address a few of differences;

  • Merge Sort demands a copy of the data structure, whereas Quick Sort applies the changes with no requirement of extra space allocated,
  • Both of the algorithms split the given data structure. However, alternatively Merge Sort intends to split from the half to divide the left and right subsets into individual elements, whereas the Quick Sort picks a partition point and swaps the lower and greater values in the right and the left directions.


  1. The algorithm divides the array into half smaller chunks until the individual items left with by using recursion,
  2. once individuals created, they are compared and merged back from smaller to larger arrays
  3. Merge sort requires extra space allocation which makes it space complexity as O(n), whereas Quick Sort only keeps a space while swapping which makes its space complexity as O(log n). However the only similarity is that because of the recursive calls, the stack traces will be created upon each call that’s also considered as a space


  • leftPointer: A pointer of the left/begin of the array
  • rightPointer: A pointer of the right/endof the array
  • middleElementPointer: Represents the element in the center of the array
  • leftArray: The elements of the left side as a temporary storage
  • rightArray: The elements of the rıght side as a temporary storage


You can checkout my GitHub repository @

Quick Sort

Reading Time: < 1 minute


Quick sort is a very efficient algorithm that leverages the divide-and-conquer principle to sort a data structure. The calculated performance complexity of Quick Sort  as follows;

  1. Best Case: O(n log n),
  2. Average Case: O(n log n),
  3. Worse Case: O(n2), reason: the algorithm will select only one element in each iteration
  4. Space Complexity: O(log n).


Furthermore, for starters, it will be a good practice to apprehend the terms in this algorithm;

  • Pivot: A reference element that is used as a line whose left and rights elements are divided. There are a few Quick Sort implementations, whose suggestions vary from picking the Pivot from the beginning, middle, end or randomly,
  • Partition: It is a practice that swaps elements on the left and right ends, while using the Pivot as a reference. By the end of Partitioning, a partition point for the next divided subsets(those will be divided also) is returned,
  • Left Pointer: A pointer or an index value that traverses on the last/low/left subset of the designated array,
  • Right Pointer: A pointer or an index value that traverses on the last/low/right subset of the designated array,

Internal of the Algorithm

In every step, the Quick Sort divides the array to subsets and aims to collect the lower numbers on the left side, the greater numbers  on the right side of the pivot in an ascending format. Let’s look at a glance how the code performs the operation;

  1. Choosing a Pivot,
  2. Beginning the partitioning by swapping the lower elements on the left, greater elements on the right side of the pivot,
  3. Apply partitioning on the left side and later on the right side.


you can checkout my GitHub repository @

Selection Sort

Reading Time: < 1 minute


Selection Sort searches through the list of array to find the smallest item in the unsorted list.
Sorting starts from the left to the right, all the sorted elements reside on the left side of the array.
Selection sort is not a fast algorithm, because it uses nested loops to sort. It comes handy when we sort smaller data sets. It’s worse-case run time complexity is O(n2)


The code can be also found in my Github Repository @

Big O Notation

Reading Time: 4 minutes


The Big O Notation is simplified analysis of an algorithm’s efficiency. It is also known as Landau’s Symbol. Big O Notation is used in Computer Science and Mathematics to describe the Asymptotic behavior of functions. Let’s study some of the characteristics;

  1. Big O Notation enlightens about the complexity of a target algorithm for a given input considered as “N”,
  2. Big O Notation is the abstraction of the efficiency in terms of the machine independence. The Algorithm must perform the same way on every operation system and hardware.
  3. Big O Notation does not concern about how much of time that an algorithm takes but how it performs under certain situations.
  4. Big O Notation gives us the “Time” and the “Space” constraints.

In addition to the second characteristic; when we run a program, we will have performance that is how much of time or hardware resource is used, and complexity how the algorithm acts and grows. Note that the Complexity affects the performance, but the other way around is not possible.

Furthermore, there are three types of measurements that I’ll explain and demonstrate those measurements in a different chapter.


Drop the constants

If you have a function that has a running time of 5N, that is realized as O(n). Because n gets bigger and the 5 is not the consideration anymore,

Observe all inputs

Different inputs and variables have different weights on identifying the notation. If you iterate in two different arrays you get O(a*b). Study the following pseudo code;

method(int[] array1, int[] array2){

For(int a : array1){//O(a)

For(int b : arrayb){//O(b)





Drop the low order terms

Certain terms dominate the other terms, in this case we drop the lower term(s). Here is the sequence of the terms. From the right to the left domination gets lower:

O(1) < O(log n) < O(n) < O(n log n) < O(n2) < O(2n) < O(n!)


Big O Notation can be used to describe the Time Complexity and the Space Complexity of algorithms. Each of these subjects are different terms.

Time Complexity

The Time Complexity corresponds to the amount of time that an Algorithm takes to run. The Time Complexity has the following cases; Best, Average and Worst.

Space Complexity

The Space Complexity describes how much of a space the algorithm allocates in the memory according to the amount of given data.


In Big O Notation we have three cases:

  1. Best Case,
  2. Average Case,
  3. Worst Case

When algorithms are analyzed, generally “Worst Case is referred. It doesn’t mean that the rest of the cases are less important, but depending on the input, the Worst Case has a weight.


image courtesy

O(1) Constant

Constant time is a basic statement that has only Constants, in a different way the values that are solid and will not change. Regardless of amount of the data, the code executes the process in the time amount, this can be a variable definition, access in an array or a print out. The simplest examples would go for this:

Int x = (9/2)*12-1;

To find out the Big O Notation of such constants; a = (9/2)*12-1;//O(1) b = 100/2; //O(1) result a+b; //O(1)

System.out.println(result); //O(1)

Total time spent: O(1) + O(1) + O(1) + O(1) = O(1)


(Constants are dropped)

O(n) Linear

linear time is known as the completion time grows for the given amount of data. A good example to it is the linear search in a loop that iterates through N amount of elements.

1.for(int i=0; i<N; i++){//O(n)



Total time spent: O(n)*O(1)=O(n) x = 55*3+(10-9); //O(1)

for(int i=0; i<N; i++){//O(n){


Total time spent: O(1) + O(n)*O(1)=O(n)

(Drop low order terms)

O(n2) Quadratic

the time completion of quadratic algorithms is proportional to the square of the given amount of data. Commonly we spot these sorts of algorithms in nested loops. In addition, the more nested loops exist, the square will become cubic O(n3) or more. The good example is the Bubble Sort. Furthermore, such algorithms dramatically hamper the performance if the amount of data increases.


Exponential algorithms are those whose performance doubles for every given input. We can basically spot such algorithms in recursive methods of calculations. For the sake of simplicity, I’ll give an example of Fibonacci numbers. As you will see, the method will call itself twice for the given input.

public int fibonacciNumbers(int number) {

  if (number <= 1) {

    return number;

  } else {

    return fibonacciNumbers(number - 1) + fibonacciNumbers(number - 2);



O(n!) Factorial

Factorial algorithm that calculates all permutation of a given array is considered as O(n!). The most suitable example of this is the travelling sales man problem with the brute-force search.

O(log n) Logarithmic

The best way to explain logarithmic algorithms is to search in chunks of data by quadratic them and the rest will be assumed as O(n). Since we split it we will gain some time while looking up. The good world example would be the Binary Search Tree for these types of algorithms and they are very efficient, because increasing the amount of data has a minor effect at some point, because the amount of data is halved each time as it is seen with the Binary Search Tree.

O(n log n) Quasi Linear

Quasi linear algorithms are the ones hard to spot. The given values will be compared once. Essentially each comparison will reduce the possible final sorted data structure in half like in O(log n). Furthermore, the number of comparisons that will be performed is equal to log in the factorial of “n”. The comparisons are also equal to n log n this is how O(n log n) algorithms are formed. The mathematical representation as follows;

Sum of comparisons are equal to log n!

Divided comparisons are equal to log n + log(n-1) + … +log(1)//End of comparisons

The outcome is equal to n log n

Examples of Quasi linear complexities are Merge and Heap Sorts.

Further Reading

  1. Big O Cheat Sheet: A great web site that points out the Time and Space complexities of Data Structures and Algorithms.
  2. Stackoverflow Post: While making my research, I found an explanation of John very easy to explain Notations by using the same example.

Binary Tree

Reading Time: 6 minutes


Binary tree is a non-linear data structure that is composed of two nodes at most. This is how the name “Binary” is formed. However, it is not necessary for the Child Nodes that they have to have two nodes, in fact they can have even zero, we will observe such types in the following chapters.

Furthermore, there is also a Binary Tree implementation called “Binary Search Tree(a.k.a ordered binary tree)” that preserves data in a sorted fashion. From this point on, we will be talking and focusing on Binary Search Tree. Let’s apprehend the characteristics of Binary Search Tree:

  • Given key is compared to the root key, the lower placed on the left and the greater placed on the right,
  • There are two ways of traversals; breadth first and depth first (will be detailed in a sub chapter) compared to one-dimensional arrays and linked lists,
  • Average cases of Positional Access, Search, Insertion and Deletion operations are far faster in tree that is denoted as O(log n) in the Big O time complexity.

Additionally, during my research, I have found a very useful resource that exposes a visualized Binary Search Tree and its operations;

Let’s look into the source code how we can create a Binary Tree.

public class Node {
    Node leftNode;
    Node rightNode;
    int key;

    Node(int key) {
        this.key = key;

public class BinaryTree {

    private Node rootNode;
    private final static int DATA_NOT_AVAILABLE = -1;

//The rest of the code can be obtained on GitHub

Glossary and Properties

Before diving into Binary Search Tree, we will need to have a ubiquitous language to apprehend all the terms used in this data structure.

Binary Tree Glossary

Root: The only top most element that has no other nodes above it,

Node: Every member in the tree is known as Node including the root as well,

Parent Node: The node that has two children,

Child Node: A node that is associated with a parent node

Leaf: A leaf is a node that DOES NOT have any children,

Path/Edge: The lines that connect all available nodes,

Sub tree: It is a triangle shape in a tree. Essentially a parent with its two child nodes,

Height: The height of a tree is the number of the edges from the Root node to its deepest leaf.

Some Binary Tree Height Samples as follow:

Binary Tree Glossary Height is three

Binary Tree Glossary height is four

Time and Space Complexities of Binary Tree

Binary Tree Big O Notation Image courtesy:

Types of Binary Trees

Full Binary Tree

Full Binary TreeFull Binary Tree is a tree type that consists of a rule that indicates that leaves can have zero or nodes have two children.

L + I + 1

L: Number of leaf nodes,

I: Number of internal nodes

Complete Binary Tree

Complete Binary TreeComplete Tree is a type of a Binary Tree in which;

  1. Every level must be completely filled,
  2. All leaf elements must lean towards left direction,
  3. Exceptionally the last leaf might have a right child node

Furthermore, Complete Binary Tree is also a Heap

Perfect Binary Tree

Perfect Binary Tree consists of Full and Complete Binary Trees with two conditions of :

  • all nodes have two children,
  • all leaves are on the same level.

In addition, the height of tree is 2h – 1

Balanced Binary Tree

Balanced and Unbalanced TreesA Balanced Tree is composed of a balance between the left and the right nodes, but at most one side differs only by one, otherwise it will be considered as an Unbalanced Tree. The operations in a balanced tree are performed in O(log n) notation where n is the node number.
In Addition, Balanced Tree Type has other implementations such as AVL, Red-Black, Weight and Height Balanced Trees etc. It is a good practice to apprehend the definition of the balanced tree.

Unbalanced Binary Tree

Unbalanced TreeOrdered data sets make up the unbalanced tree. In this type, most of the nodes are located on one side of the tree. In Unbalanced Trees, we cannot favor of fast operations denoted as O(log n), whereas it is actually O(n).

Tree Traversal

Tree Traversal is the acronym that is known as Tree Search is a type of an action that leads to visiting every single node in the tree and performing selection, insertion, updating and deletion. While going/traversing through there are number of ways to do so namely; Breadth First and Depth First traversals.

Tree Traversal

Breadth First Traversal

Breadth First Tree Traversal

Breadth First Traversal traverses the tree in a level fashion. It internally utilizes a Queue Data Structure, to visit nodes in layers as you can see the illustration. The algorithm of Breadth First Traversal goes;

public void breadthFirstTraversal() {
        if (rootNode == null)
        System.out.printf("***Breadth First Traversal***\n");
        Queue<Node> queue = new ArrayDeque<>();
        while (!queue.isEmpty()) {
            rootNode = queue.remove();
            if (rootNode.leftNode != null)
            if (rootNode.rightNode != null)

Console Output:

***Breadth First Traversal***

Depth First Traversal

Deep First travel is slightly different and more complicated compared to the Breadth first traversal. Basically, Depth first traversal, the actual focus is not the levels and layers but the Depth itself. Depth first algorithms will visit each node.

In Order Traversal

In Order Traversal

In Order Traversal has the following sequence:

  1. Left Node,
  2. Root Node,
  3. Right Node

Having said that when the traversal begins from the deepest left node. As the second item goes to the root, it is not the top root but the parent root. Then it follows the right node. As you see the above illustration, the algorithm starts in “45” the deepest left node and ends in “77” the highest right node in the tree. Observe the code for traversal:

private void inOrderTraversal(Node node) {

        if (node != null) {






Console Output:

***In Order Traversal***

Pre Order Traversal

Pre Order Traversal

Pre Order Traversal has the following sequence:

  1. Root Node,
  2. Left Node,
  3. Right Node

Having said that when the traversal begins from the root node. As the second item goes to the next left root. Then here the algorithm starts to visit the left and accordingly the right node. As you see the above illustration, the algorithm starts in “60” the root node and ends in “77” the highest right node in the tree. Observe the code for traversal:

private void preOrderTraversal(Node node) {

        if (node != null) {






Console Output:

***Pre Order Traversal***

Post Order Traversal

Post Order Traversal

Post Order Traversal has the following sequence:

  1. Left Node,
  2. Right Node,
  3. Root Node

Having said that when the traversal begins from the deepest left node. As the second item goes to the next right node. Last of all it visits the root node of the children. As you see the above illustration, the algorithm starts in “45” the deepest left node and ends in “60” the root node. Observe the code for traversal:

private void postOrderTraversal(Node node) {

        if (node != null) {






Console Output:

***Post Order Traversal***


The full source code of the Binary Tree and the test cases can be obtained from my public GitHub repository. There will be more utility methods and test cases covering the chapter.

Creating a Java keystore

Reading Time: < 1 minute

create a keystore file

$JAVA_HOME/bin/keytool -genkey -alias -keyalg
RSA -keystore keystore.jks -keysize 2048


Generate a certificate signing request (CSR) for an existing Java keystore

$JAVA_HOME/bin/keytool -certreq -alias -keysto
re keystore.jks -file

Import a root or intermediate CA certificate to an existing Java keystore

$JAVA_HOME/bin/keytool -import -trustcacerts -alias root -file
 intermediate.crt -keystore keystore.jks

check certificates in keystore

$JAVA_HOME/bin/keytool -list -v -keystore keystore.jks

Check specific keystore entry using an alias

$JAVA_HOME/bin/keytool -list -v -keystore keystore.jks -alias mydomain


Bootstrap a sample blog post details/read more page

Reading Time: 2 minutes


<!DOCTYPE html>
<html lang=”en”>
<meta charset=”utf-8″>
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>
<meta name=”viewport” content=”width=device-width, initial-scale=1″>

<link rel=”stylesheet” href=”” integrity=”sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp” crossorigin=”anonymous”>
<link rel=”stylesheet” href=”” integrity=”sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u” crossorigin=”anonymous”>

<style type=”text/css”>
body {
background: #eee !important;

margin-top: 0 !important;
padding-top: 0;
margin-bottom: 15px;
<!– HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries –>
<!– WARNING: Respond.js doesn’t work if you view the page via file:// –>
<!–[if lt IE 9]>
<script src=””></script>
<script src=””></script>

<div class=”container”>
<div class=”row”>
<div class=”col-lg-9″>
<div class=”panel panel-default”>
<div class=”panel-body”>
<div class=”page-header”>
<h3>Page Header Section</h3>
<img class=”featuredImg” src=”×433/2014/10/13/0ea985b4-9f3a-43d0-9a47-21154c864996/samsung-galaxy-note-4-9024.jpg” width=”100%”>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>

<h4>Another heading</h4>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>

<script src=””></script>
<script src=”” integrity=”sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa” crossorigin=”anonymous”></script>