Binary tree - Data structure


What differ a binary tree from a standard tree data structure is binary tree parent can only hold 2 children (from left side and right side).

Advantages of using a binary tree is it combines both good qualities of ordered array and linked lists.

  • Fast search (Like using ordered array and binary search)
  • Fast insertion/deletion (Like in a linked list)

Image obtained from : https://upload.wikimedia.org/wikibooks/en/4/41/HSE_ch5_binary_tree.png

















Following figure illustrates how search/add items work on a BST.



Tree Traversal 

Since tree is not a linear data structure like array or lists or queues, there are more than one way of traversing through a tree.Tree traversal simply means that you start at a node and go through each node only once.

We have 2 kinds of traversal.(This is also valid for graphs also. In fact these traversals came from graphs because tree is a special kind of a graph. )

  • Depth first traversal (also called as level order trversal)
  • Breadth first travesal
    • Pre order (visiting order root -> left sub tree -> right sub tree)
    • In order (visiting order left sub tree -> root ->  right sub tree)
    • Post order (visiting order left sub tree ->  right sub tree -> root )
Image

Breadth first(level order): A,B,C,D,E,F,G,H,I (finish each level then go to next level)
Pre order: A,B,D,E,H,I,C,F,G (Only after finishing nodes left sub tree, move to right sub tree)
In order: D,B,H,E,I,A,F,C,G (First finish nodes left and node and nodes right)
Post order: D,H,I,E,B,F,G,C,A (Unless left and right sub trees are done, dont visit middle node)


Level order traversal (Depth first) process

  • Hopefully we have a root node. Otherwise how can we traverse :p 
  • We can use a queue for this type of traversal.
  • En-queue a node.
  • Print that node or do anything with that node so it is visited.
  • De-queue that node. But before de-queuing, enqueue it's child nodes to the queue.
  • Do this until all the nodes are over in the BST. 

Pre order/in order/post order traversal process

  •  Select a node
  • Visit that node
  • Then visit its left node. (If that node also has a left, process is similar)
  • after visiting left node,visit its right node ( (If that node also has a left, process is similar))
In in order and post order traversals the process is similar. Only the node,left,right sequences gets changed.


Binary search tree - node - Java code (For illustration)


package BinaryTreePackage;

import java.util.LinkedList;
import java.util.Queue;

public class Node {

 int data;
 Node left;
 Node right;
 
 public Node(int data) {

  this.data = data;
 }
 
 //-----------------------------------------
 // Add nodes
 // ----------------------------------------
 public void addNode(int value)
 {
  
  if(value == data){ System.out.println("Similar values!");}
  
  if(value < data)
  {
   if( left==null ){ left = new Node(value); }
   else{left.addNode(value); System.out.println("added:" + value);}
  }
  else
  { 
   if( right==null ){ right = new Node(value);  }
   else{right.addNode(value);System.out.println("added:" + value);}
  }
  
  
 }


 //-----------------------------------------
 // Search nodes
 // ----------------------------------------
 public void search(int value) {
  
  if (data==value) {System.out.println("Item found:"+data);   }
  else if(data > value)
  {
   if (left==null) {
     System.out.println("Item not found!");
   } else {
     left.search(value);
   }
  }
  else 
  {
   if (right==null) {
     System.out.println("Item not found!");
   } else {
     right.search(value);
   }
  }
 }
 
 //-----------------------------------------
 // Depth first (level order traversal)
 // ----------------------------------------
  
 public void levelOrderTraversal(Node root)
 {
  System.err.println("Initiating level order traversal");
  
  if( root==null )System.out.println("No nodes in BST"); 
  Queue queue = new LinkedList();
  queue.add(root);
  
  while (!queue.isEmpty()) {
    
   Node current = queue.poll();
   System.out.print("-"+current.data);
   
   if(current.left != null)
   { queue.add(current.left);}


   if(current.right != null)
   { queue.add(current.right); }
  }
  
 }

 public void preOrderTraversal(Node current) {

  if (current == null) return;
  System.out.print(current.data+"-");
  
  preOrderTraversal(current.left);
  preOrderTraversal(current.right);

 }

 public void inOrderTraversal(Node current) {
  
  if (current == null) return;
  inOrderTraversal(current.left);
  System.out.print(current.data+"-");
  inOrderTraversal(current.right);

 }

 public void postOrderTraversal(Node current) {
  
  if (current == null) return;
  postOrderTraversal(current.left);
  postOrderTraversal(current.right);
  System.out.print(current.data+"-");
 }
 
 }

Binary search tree - Tree - Java code

This class's goal is to crate an object that can hold other node objects and form the tress structure along with its operation.
package BinaryTreePackage;

public class BinaryTree {

 private Node root;
 
 public BinaryTree() {
  root = null;
 }
 
 public void addNode(int value)
 {
  if(root==null){root = new Node(value); }
  else{root.addNode(value);}
 }
 
 
 public void search(int value)
 {
  if (root==null) {System.out.println("No items in BST");  }
  else{root.search(value);}
 }
 
 
 public void levelOrderTraversal()
 {
  if(root==null) return;
  else root.levelOrderTraversal(root);
 }

 public void preOrderTraversal()
 {
  System.out.println("Initiating pre order traversal");
  if(root ==null) return;
  else root.preOrderTraversal(root);
 }
 
 public void inOrderTraversal()
 {
  System.out.println("Initiating in order traversal");
  if(root ==null) return;
  else root.inOrderTraversal(root);
 }
 
 public void postOrderTraversal()
 {
  System.out.println("Initiating post order traversal");
  if(root ==null) return;
  else root.postOrderTraversal(root);
 }
 
}







Share:

Tree - Data strucrure

Data structures like array, linked lists, stacks, queues are linear data structures.
Tree data structure is a non-linear data structure and its good to use in hierarchical data situations.

Image obtained from : http://www.teach-ict.com/as_as_computing/ocr/H447/F453/3_3_5/data_structures/miniweb/images/tree.jpg


Tree terminogy

Lets say we have a tree T with set of nodes where nodes have parent child relationship.

root - which has no parents. Only one root is in T
nodes - nodes other than root are called nodes and they all have a parent. and may be children as well
siblings - if some nodes share a same parent they are called siblings
internal nodes - If a node has children its is a internal nodes
external nodes/leaves - if a node has no children it is an external node or a leave
edge - A connection between parent and a child
path - sequence of edges from a source node to destination node
ordered tree - where siblings have a meaningful linear fashion relationship

There are various kinds of trees that can be implemented using these concepts.
Ex: Binary threes, red black treens, 234 trees.
Share:

Doubly Linked List - Data Structure

One natural characteristic of singly linked list (SLL)is that it is asymmetric. Meaning a node only knows its next node. In doubly linked list (DLL) a node can refer to its previous and next nodes.









Image obtained from : http://www.cs.usfca.edu/~srollins/courses/cs112-f07/web/notes/linkedlists/ll5.gif

In DLL we need 2 sentinels (Dummy nodes) for header and trailer.

Initially empty list is created so that,
header.next -----points to ------>  trailer
trailer.prev -----points to -------> header

header and trailer sentinels(dummy nodes) never change. Their next and prev changes with the intermediate nodes.


Doubly linked lists implementation - for illustration purposes



private static class Node<E> {
  private E element;
  private Node<E> prev;          // this the only additional reference comparing with singly linked list 
  private Node<E> next;

  public Node(E e, Node<E> p, Node<E> n) {
   element = e;
   prev = p;
   next = n;
  }
}


public class DoublyLinkedList<E> {

  private Node<E> header;   // header and trailer sentimental for setting up the boundary of the list
  private Node<E> trailer;
  private int size = 0;


public DoublyLinkedList( ) {
  header = new Node<>(null, null, null);      // initiall creates an emptry list where header and trailer
  trailer = new Node<>(null, header, null);   // sentinels are referred to each other
  header.setNext(trailer);
 }



public int size( ) { return size; }


public boolean isEmpty( ) { return size == 0; }

public E first( ) {
  if (isEmpty( )) return null;
  return header.getNext( ).getElement( );
}


public E last( ) {
  if (isEmpty( )) return null;
  return trailer.getPrev( ).getElement( );
}


public void addFirst(E e) {
  addBetween(e, header, header.getNext( ));    // adds e node between header and header.next
 }


public void addLast(E e) {
  addBetween(e, trailer.getPrev( ), trailer);     // add e node between trailer and trailer.prev
}


public E removeFirst( ) {
  if (isEmpty( )) return null;                       // cant remove node from an empty list
  return remove(header.getNext( ));          
}


public E removeLast( ) {
  if (isEmpty( )) return null;
  return remove(trailer.getPrev( ));
}


private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
  
  // newest node's next and previous is set to left side and right side nodes
  Node<E> newest = new Node<>(e, predecessor, successor);
 // left sides nodes next is set to newest node
  predecessor.setNext(newest);
  //right side nodes previous is set to newest node
  successor.setPrev(newest);
  size++;
}

private E remove(Node<E> node) {
  Node<E> predecessor = node.getPrev( );    // Temporary predecessor and successor is set
  Node<E> successor = node.getNext( );       //  their next and prev is set to each other
  predecessor.setNext(successor);                 //
  successor.setPrev(predecessor);                  //
  size−−;
  return node.getElement( );
}
Share:

Circular Linked Lists - Data Structures

There are some times data can be efficiently stored in a linked list like data structure but in a circular fashion. Just like a wheel. That is when circular linked lists come to play.


Basics about RR algorithm 

Round-robin (RR) is one of the algorithms employed by process and network schedulers in computing. As the term is generally used, time slices are assigned to each process in equal portions and in circular order, handling all processes without priority (also known as cyclic executive).  - Wikipedia

What happens basically in RR is to schedule processes in an OS or a packets in a network. Each process is given a time slice to execute (ie: a certain time period ). When time slice is for a process is over it is being interrupted no matter the process is completed or not. Inactive processes are removed. Each active process is given a time slice.

RR can be implemented using linked list as well.

process p = Linked List.removeFirst( )       // remove process from first
Give a time slice to process p
Linked List.addLast(p)         // add process to last

Although this is possible with a singly linked list there are inefficiencies. This is because the same node removed from the first and inserted at the last end. Plus additional computations with regard to this (ex: numberOfNodes --numberOfNodes ++ ) have to be executed redundantly.


Circular linked list

What is different with circular LL and singly LL ?
-- singly LL's tail node'next refers to null
-- circular LL's tail node'next refers to head node

In circular ll it is enough to maintain head or tale reference because head can be located by tale.next reference.


Image obtained from :https://en.wikipedia.org/wiki/Linked_list



Implementation of Circular Linked List (CCL) ( except node implementation)

public class CircularlyLinkedList<E> {

private Node<E> tail = null;    // tail is referred to null initially
private int size = 0;                  // initial size is is 0

public CircularlyLinkedList( ) { }     // If needed tail and size could be initialized here

public int size( ) { return size; }     // gives number of nodes in CLL

public boolean isEmpty( ) { return size == 0; }       // Checks if CCL is empty


public E first( ) {
  if (isEmpty( )) return null;
  return tail.getNext( ).getElement( );       // return tail.next. which means the first node
}


public E last( ) {
  if (isEmpty( )) return null;
  return tail.getElement( );                  // returns tail node
}


public void rotate( ) {
  if (tail != null)
  tail = tail.getNext( );                      // tail reference is passed to next node
}                                                     // number of nodes doescnt change except for tail position


public void addFirst(E e) {

  if (size == 0) {
    tail = new Node<>(e, null);       // at first the tail is the new node. new node is also the first node
    tail.setNext(tail);
  } 
 else {
    Node<E> newest = new Node<>(e, tail.getNext( ));     // newly added node refers to previous head
    tail.setNext(newest);                                           // tail stays the same because insertion is at front. new tail.next that means head refers to the newly added node
 }
 size++;
}



public void addLast(E e) {
   addFirst(e);                           // add a node to front
   tail = tail.getNext( );            // set tail to front added node
}


public E removeFirst( ) {
  if (isEmpty( )) return null;                   // cant remove nodes from an empty list

 Node<E> temp = tail.getNext( );              // head node is assigned to a node

 if (head == tail) tail = null;                    // When there is only one node left

 else {
   tail.setNext(head.getNext( ));           // tail stays the same. tail.next is referred to temp.next
   size−−;
   return head.getElement( );
 }
}

Share:

Singly Linked List - Data structure

One major advantage with using arrays as a data structure is it is always fixed size. Linked lists data structure can solve that storage limit with arrays. Lists have in flavours of singly and doubly. We will consider singly lists here.

Singly linked lists are like a chain. You have the first node and you can keep adding nodes for infinity. One thing is to identify the ends of the chain we have some mechanisms like painting chain ends in different colors.

Basic feature of linked lists

Linked list is composed node nodes.
Each node has to parts. 
- First part is to store data(ints, strings or object types). 
- Second part is to store a reference to the next node. (Like in the chain example)
First node is called the head node. (This is how we identify the front)
Last node is marked as the node where its next is null which means not references to any node
size can be introduced as a variable to detect lists number of items in any given time.



Image obtained from : http://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html




Node declaration in Java (For illustration purposes)



private static class Node<E>
{
   private E data;
   private Node<E> next;

   public Node(E d, Node<E> n)
   {
      data = d;
      next = n;
   }
}

Linked List Operations in Java - (For illustration purposes)


Adding a data item from the head of the lists

Process addFirst(e):
newest = Node(e)       // New node is created to add first
newest.next = head    // created nodes next reference is pointed to current head node
head = newest            // Set newly added node as the head
size = size + 1           // now that a new node is added to the chain increment its size by 1


Adding a data item from the back of the list

Process addLast(e):
newest = Node(e)       // create a new node to add at the last
newest.next = null     // to make newly created node last node, set its next to last
tail.next = newest      // set current tails next to newly crated node. So that current tails is now 1 node before last
tail = newest              // set tail to newly created node so that it is officialy the last node
size = size + 1           // now that a new node is added to the chain increment its size by 1

Remove data item from the head of the list

Process removeFirst( ):
if head == null then the list is empty // This is because cant remove a node from an empty list
head = head.next        // new head is set to next node. So that 2nd node is the new head 
size = size − 1     // New lists has 1 item less. But the reference from old new to new new is there


one major disadvantage in linked lists is it consumes more memory. This is because of the additional part for storing the reference.

See full implementation details here : http://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html









Share:

Data structure 1 - Array

One most basic and most popular data structure is array. It is so hard to find a programming language where there is no arrays defined.  Normally arrays can hold primitive data types such as ints, floats, booleans and such but you can create arrays to hold more complex user defined data types as well. In here the focus is not to show you how to create an array, how to insert an item to array and such. Those depends on the prog language you are using. More focus in here is to analyse the data structure and basic actions that can be performed on arrays.

So to have it formally start, array with n elements can have addresses ranging from 0th index to (n-1)th index. Thats it. :) And basically you can insert an item to an array, search for an item and delete an item from array. Here we will look an un-ordered array. We will look at ordered array data structure in a another example. This is because when it is ordered it has some certain advantages. ;)

No duplicates

You can insert duplicate data to an array.There is no problem with that. Lets see such a scenario.

Insert - you can insert your data item to next available space. 1 move.
Search - When you want to search a data item it can be at the first index. So 1 move. Worst case is it can be at the last index. So n moves. So depending on where it resides number of steps differs. So it is fair to say it takes n/2 moves on average for searching.
Delete - Before you search you have to first find it. And after deletion you have to restructure the array so that items from right side of the deleted item are moved 1 place left. So on average for search the item it takes n/2 moves.  So using the same logic it takes on average n/2 moves to restructure. 


With duplicates

Insert -  You can just insert an item to an array. no matter it is a duplicate or not. So 1 move.
Search - You cant just stop finding the first element that you are looking for. Because there can more of that in the array. So you will have to search fro the whole array to search a specific item. So n moves.
Delete - Just like no duplicates example logic, n moves to search. Then on average n/2 moves to restructure after deletion.   
Share:

Data structures and Algorithms overview

In order to proceed with DSA (Data structures and Algorithms) you have to have some basic programming background. It is not always the case. You  can learn the concepts of DSA prior to learning programming. But personally I do not recommend the latter. Just an personal opinion. Lets understand the things very simply. ;)


Data structure 

Normally in a computer program, no matter in what language you write it we need data to work with. These data can be variables (int x= 25, String firstName = "kalpa" , boolean isSignedIn = false) or data that we store in a database (may be in an xml file , database like mySQL or simply a text file). Amount of data and the complexity of data increase the with program scale and complexity. For example when you code a basic calculator you may need some ints doubles, floats. But when it comes to enterprise level real time banking mobile application nature of data differs. 

So not all the data are alike. These data has to be stored in some sort of manner in order to use it. Hence we need some kind of structure to hold on that data. (no matter the data is in variables or a database).





Simply saying you cant store eggs and oranges in the same manner. You need specific structures to each type. Read more about DS from here.

Algorithms

Well, the name seems cool mathematicy, cody and geeky. But in simple terms an algorithm is way of solving a problems. In day to day life we use algorithms all the time. For example when we want to tie our shoes we have certain way answering that problem. You take the shoe laces tie it in a certain fashion. VIOLA ! your shoe is laced. :D all the time, in every nook and corner in the world this algorithm is the same. 
Algoithm can be simple as this

or it can be complex as this. :D

Normally algorithms are kind complex. ;)

Algorithms can be used with data structure also.
  • To insert a new data item (Adding a new orange to the orange basket basket)
  • To search for a specific data item (search a specific orange from the basket. This may take some time depending in how you have strucutred your oranges)
  • To delete a data item (get an odd yellow colored orange and throw it to garbage can.)
For more on algos read some from here



Share: