Showing posts with label singly linked list. Show all posts
Showing posts with label singly linked list. Show all posts

16 December 2010

Linked List : Given a pointer to any node, delete the node pointed by the pointer

Given a linked list like this,


Given a pointer to any node, delete the node pointed by the pointer. Note: no head pointer is given.

Solution:

Assume a pointer to p3, lets call it to 'p'. Since only pointer to current node is provided, there is no way to delete the current node from the list. But instead of deleting the current node, we can just move the next node data to current node and delete the next node. The algorithm can be explained simply as,

Cheers!!
Jack

06 March 2010

Reverse a Singly Linked List Recursively in Java

We have already seen how to reverse a singly linked list with illustrative pictures. Now lets see how we can do it recursively. In the previous problem we did it iteratively, now we shall do it recursively.
To attack any problem in a recursive approach, we need to be very clear about the end/boundary conditions. For a linked list, reverse of a null list or reverse of list of size 1 is going to be the same.
Reverse of a linked list of size x will be the reverse of the 'next' element followed by first.
A picture means a thousand words. So, here is what happens internally.

Now for the comprehensive Java code (reference for SinglyLinkedList implementation can be found here)


Cheers,
Bragaadeesh.

21 February 2010

Stack using Linked Lists in Java

Stack is a data structure that follows the simple FILO (First In, Last out) or LIFO (Last In, First Out) rule. Imagine a real world stack where you arrange Notebooks one over the other. The first notebook you insert will be at the bottom and that will come only at last. The implementation of stack can be done in many ways. We are going to see how to make use of a Singly Linked List to the use.
We can implement stack using a Linked List in the below shown ways. One is to have the END node on top and other is to have the START node at the top. If we recollect the singly linked list data structure, insertAtFirst() is an operation which can be done in O(1) time and insertAtLast() will take O(n) time (because we need to traverse till the last node). So, we can make use of the second method to use stack using linkedlists.

The three methods that stands out for a stack are pop(), push() and peek().
push() - push elements into a stack. We will use the insertAtFirst() method of LinkedList. Throws StackOverflowException when the stack is full.
pop() - remove and returns the top element from a stack. We will use the removeAtFirst() method of LinkedList. Throws StackEmptyException when the stack is empty.
peek() - return the top element from the stack without removing it. We will use the getFirst() method of LinkedList. Throws StackEmptyException when the stack is empty.

The java code for this looks very simpler. We will make use of the existing SinglyLinkedList class that we have used before.

package dsa.stack;

import dsa.linkedlist.SinglyLinkedList;

public class Stack<E> extends SinglyLinkedList<E>{
 
 public static final int MAX_STACK_SIZE = 100;
 
 public E pop() throws StackEmptyException{
  if(this.size()==0){
   throw new StackEmptyException();
  }
  return this.removeAtFirst();
 }
 
 public E peek() throws StackEmptyException{
  if(this.size()==0){
   throw new StackEmptyException();
  }
  return this.getFirst().data;
 }
 
 public void push(E data) throws StackOverflowException{
  if(this.size()>MAX_STACK_SIZE){
   throw new StackOverflowException();
  }
  this.insertAtFirst(data);
 }
 
 public static void main(String args[]){
  Stack<Integer> stack = new Stack<Integer>();
  try{
   System.out.println("Pushing 1, 2, 3, 4, 5");
   stack.push(1);
   stack.push(2);
   stack.push(3);
   stack.push(4);
   stack.push(5);
   System.out.println("Pop once  : "+stack.pop());
   System.out.println("Peek once : "+stack.peek());
   System.out.println("Pop once  : "+stack.pop());
   System.out.println("Pop once  : "+stack.pop());
   System.out.println("Pop once  : "+stack.pop());
   System.out.println("Pop once  : "+stack.pop());
   System.out.println("Pop once  : "+stack.pop());
  }catch(StackEmptyException e){
   System.out.println(e.getMessage());
  }catch(StackOverflowException e){ 
   System.out.println(e.getMessage());
  }
 }
}
/*
SAMPLE OUTPUT:
Pushing 1, 2, 3, 4, 5
Pop once  : 5
Peek once : 4
Pop once  : 4
Pop once  : 3
Pop once  : 2
Pop once  : 1
Stack is empty!
*/

package dsa.stack;

public class StackEmptyException extends Exception{
 public StackEmptyException(){
  super("Stack is empty!");
 }
}
package dsa.stack;

public class StackOverflowException extends Exception{
 public StackOverflowException(){
  super("Stack Overflown");
 }
}

Cheers,
Bragaadeesh.

Find kth node from the last in a singly linked list without using counter

The objective for this program is to find the kth node from the last without actually finding the size of the singly linked list.
For this problem, we need to have two pointers, lets call them FAR and NEAR. We need to initialize them by pointing them to the start. After doing that, move the FAR pointer 'k-1' times ahead. After moving that run a loop until FAR becomes null, amidst that increment both FAR and NEAR pointers.
The below picture shown is done for k=3. In step1, we are moving the pointer k-1=2 times. After that by moving parallely FAR and NEAR pointers, we can find the kth element from the last by getting the data from NEAR pointer.

The Java code for this simple program is given below. To try the below program please copy this class as well.
package dsa.linkedlist;

public class FindKthElementFromLast {
 public static void main(String args[]){
  FindKthElementFromLast kthFromLastFinder = new FindKthElementFromLast();
  SinglyLinkedList<Integer> originalList = kthFromLastFinder.getLabRatList(8);
  System.out.println("Original List : "+originalList.toString());
  kthFromLastFinder.findFromLast(originalList, 3);
 }
 
 private void findFromLast(SinglyLinkedList<Integer> singlyLinkedList, int k) {
  Node far, near;
  //initialize far and near pointers
  far = near = singlyLinkedList.start;
  //Move the far pointer k times from the starting position
  System.out.print("kth node from last for k = "+k+" is ");
  while((k--)!=0){
   far = far.next;
  }
  while(far!=null){
   near = near.next;
   far = far.next;
  }
  System.out.println(near.data);
 }

 private SinglyLinkedList<Integer> getLabRatList(int count){
  SinglyLinkedList<Integer> sampleList = new SinglyLinkedList<Integer>();
  for(int i=1;i<=count;i++){
   sampleList.add(i);
  }
  return sampleList;
 }
}
//SAMPLE OUTPUT
//Original List : 1, 2, 3, 4, 5, 6, 7, 8
//kth node from last for k = 3 is 6
Cheers,
Bragaadeesh.

08 February 2010

Program to find center of a singly linked list in java

This is a very common data structure problem, to find the center of a singly linked list. And the following is the famous solution. I have tried to give a comprehensive code coverage for this problem. The list count can either be odd or even. If its odd, we have only one value as the center and two for even case. I have covered both in the following code. Please do take a look at the SinglyLinkedList class for this program for reference.
This is how it works, there will be two pointers, one jumping once and another one jumping twice. When the double jumper ends/terminates, the single jump fellow's data would be the center.



package dsa.linkedlist;

public class FindCenterOfAList {
 public static void main(String args[]){
  FindCenterOfAList ratList = new FindCenterOfAList();
  ratList.test(10);//TEST FOR EVEN
  ratList.test(17);//TEST FOR ODD
  ratList.test(1);//TEST FOR SINGLE
  ratList.test(0);//TEST FOR ZERO OR LESS
 }
 
 public int[] getMidItem(SinglyLinkedList<Integer> listToCheck){
  Node<Integer> singleJump = listToCheck.start;
  Node<Integer> doubleJump = listToCheck.start;
  
  while(doubleJump.next!=null && doubleJump.next.next!=null){
   singleJump = singleJump.next;
   doubleJump = doubleJump.next.next;
  }
  
  int[] midItem = null;
  
  if(doubleJump.next == null){
   midItem = new int[1];
   midItem[0] = singleJump.data;
  }else if(doubleJump.next.next == null){
   midItem = new int[2];
   midItem[0] = singleJump.data;
   midItem[1] = singleJump.next.data;
  }
  
  return midItem;
 }
 
 private void test(int sampleSize){
  if(sampleSize<1){
   System.out.println("List is empty!");
   return;
  }
  SinglyLinkedList<Integer> randomList = giveMeAList(sampleSize);
  System.out.print("For list : ");stringify(randomList);
  int[] midItem = getMidItem(randomList);
  if(midItem.length == 1){
   System.out.println("Middle Item : "+midItem[0]);
  }else if(midItem.length == 2){
   System.out.println("Middle Items : "+midItem[0]+", "+midItem[1]);
  }
  System.out.println();
  
 }
 
 private SinglyLinkedList<Integer> giveMeAList(int length){
  SinglyLinkedList<Integer> sampleList = new SinglyLinkedList<Integer>();
  for(int i=1;i<=length;i++){
   sampleList.add(i);
  }
  return sampleList;
 }
 
 private void stringify(SinglyLinkedList<Integer> ratList) {
  for(int i=0;i<ratList.size;i++){
   System.out.print(ratList.getNodeAt(i).data+" ");
  }
  System.out.println();
 }
}
/*
-------OUTPUT--------
For list : 1 2 3 4 5 6 7 8 9 10 
Middle Items : 5, 6

For list : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 
Middle Item : 9

For list : 1 
Middle Item : 1

List is empty!
*/

Cheers,
Bragaadeesh

16 January 2010

Find Loops in a Singly Linked List in Java

This is a very simple yet efficient program written in Java to find whether a Singly Linked List has loops or not. If you need the SingleLinkedList class, please click this link.
The logic is simple, there will be two pointers one traversing once and the other traversing twice. If at all we get a NullPointerException in the process we can be very sure that there are no loops. In the other case, there is definitely a loop. You may play with it. Dont forget to copy this class.
package dsa.linkedlist;

public class FindLoopsInLinkedList {
 public static void main(String args[]){
  FindLoopsInLinkedList finder = new FindLoopsInLinkedList();
  SinglyLinkedList<Integer> randomList = finder.giveMeALoopedList();
  System.out.println("Loop Existence : "+finder.doesLoopExist(randomList));
 }
 
 public boolean doesLoopExist(SinglyLinkedList<Integer> listToCheck){
  Node<Integer> singleJump = listToCheck.start;
  Node<Integer> doubleJump = listToCheck.start;
  
  try{
   while(true){
    singleJump = singleJump.next;
    doubleJump = doubleJump.next.next;
    if(singleJump == doubleJump){
     return true;
    }
   }
  }catch(NullPointerException ne){
   return false;
  }
 }
 
 private SinglyLinkedList<Integer> giveMeALoopedList(){
  SinglyLinkedList<Integer> sampleList = new SinglyLinkedList<Integer>();
  //First Insert randomly ten elements in a linked list
  for(int i=0;i<9;i++){
   sampleList.add(i);
  }
  //Force the list to have a loop in this fashion
  Node<Integer> lastNode = sampleList.getLast();
  lastNode.next = sampleList.getNodeAt(3);
  return sampleList;
 }
}
//-------OUTPUT--------
//Loop Existence : true

Cheers!
Bragaadeesh.

Java Program to reverse a Singly Linked List

Hi folks,

I have written an efficient way to reverse a Singly Linked List using three pointers/nodes for traversal/temporary purposes. I have given a pictorial representation of what happens with near, mid and far pointer. The program is mostly self explanatory. Remember, we are using our implementation of Singly Linked List. You may visit this link if you need that class.



Note : You may click on the above image to get a clearer picture.

Now, for the source code.


Cheers,
Bragaadeesh.

Singly Linked Lists in Java

Hi folks,

Linked list is one of the most discussed data structures and is frequently asked in interviews in many higher level companies like google, amazon etc., I have tried to implement the Single List comprehensively in Java.

Don't we already have a LinkedList in Java?
Yes we do. But the one that I have given here is a Single Linked List which means that we can traverse only one side. This code will be the base for all the problems in linked list that we are going to solve. I have provided both the class and its testcase.

Supporting Node datastructure for the singly linked list
package dsa.linkedlist;

public class Node<E>{
 E data;
 Node<E> next;
}

The SingleLinkedList class,
package dsa.linkedlist;

/**
 * This is a singly linked list with no prev pointer.
 * @author Braga
 * @param <E>
 */
public class SinglyLinkedList<E> {
 
 Node<E> start;
 int size;
 
 public SinglyLinkedList(){
  start = null;
  size = 0;
 }
 
 //insertAtLast
 public void add(E data){
  insertAtLast(data);
 }
 
 public void insertAtLast(E data){
  if(size==0){
   start = new Node<E>();
   start.next = null;
   start.data = data;
  }else{
   Node<E> currentNode = getNodeAt(size-1);
   Node<E> newNode = new Node<E>();
   newNode.data = data;
   newNode.next = null;
   currentNode.next = newNode;
  }
  size++;
 }
 
 public void insertAtFirst(E data){
  if(size==0){
   start = new Node<E>();
   start.next = null;
   start.data = data;
  }else{
   Node<E> newNode = new Node<E>();
   newNode.data = data;
   newNode.next = start;
   start = newNode;
  }
  size++;
 }
 
 public Node<E> getNodeAt(int nodePos) throws ArrayIndexOutOfBoundsException{
  if(nodePos>=size || nodePos<0){
   throw new ArrayIndexOutOfBoundsException();
  }
  Node<E> temp = start;//Move pointer to front
  int counter = 0;
  for(;counter<nodePos;counter++){
   temp = temp.next;
  }
  return temp;
 }
 
 public void insertAt(int position, E data){
  if(position == 0){
   insertAtFirst(data);
  }else if(position==size-1){
   insertAtLast(data);
  }else{
   Node<E> tempNode = getNodeAt(position-1);
   Node<E> newNode = new Node<E>();
   newNode.data = data;
   newNode.next = tempNode.next;
   tempNode.next = newNode;
   size++;
  }
 }
 
 public Node<E> getFirst(){
  return getNodeAt(0);
 }
 
 public Node<E> getLast(){
  return getNodeAt(size-1);
 }
 
 public E removeAtFirst(){
  if(size==0){
   throw new ArrayIndexOutOfBoundsException();
  }
  E data = start.data;
  start = start.next;
  size--;
  return data;
 }
 
 public E removeAtLast(){
  if(size==0){
   throw new ArrayIndexOutOfBoundsException();
  }
  Node<E> tempNode = getNodeAt(size-2);
  E data = tempNode.next.data;
  tempNode.next = null;
  size--;
  return data;
 }
 
 public E removeAt(int position){
  if(position==0){
   return removeAtFirst();
  }else if(position == size-1){
   return removeAtLast();
  }else{
   Node<E> tempNode = getNodeAt(position-1);
   E data = tempNode.next.data;
   tempNode.next = tempNode.next.next;
   size--;
   return data;
  }
 }
 
 public int size(){
  return size;
 }
 
 public String toString(){
  if(size==0){
   return "";
  }else{
   StringBuilder output = new StringBuilder();
   Node<E> tempNode = start;
   while(tempNode.next!=null){
    output.append(tempNode.data).append(", ");
    tempNode = tempNode.next;
   }
   output.append(tempNode.data);
   return output.toString();
  }
 }
 
}


The JUnit test for the SingleLinkedList class
package dsa.linkedlist;

import junit.framework.TestCase;

public class SinglyLinkedListTest extends TestCase{
 
 private int labRats;
 
 public void setUp(){
  labRats = 10;
 }
 
 public void testAdd(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  sampleList.add(100);
  assertEquals(sampleList.getLast().data.intValue(),100);
 }
 
 public void testInsertAtLast(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  sampleList.insertAtLast(100);
  assertEquals(sampleList.getLast().data.intValue(),100);
 }
 
 public void testInsertAtFirst(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  sampleList.insertAtFirst(100);
  assertEquals(sampleList.getFirst().data.intValue(),100);
 }
 
 public void testInsertAt(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  sampleList.insertAt(2, 100);
  assertEquals(sampleList.getNodeAt(2).data.intValue(),100);
 }
 
 public void testGetNodeAt(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  assertEquals(sampleList.getNodeAt(2).data.intValue(),2);
 }
 
 public void testGetFirst(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  assertEquals(sampleList.getFirst().data.intValue(),0);
 }
 
 public void testGetLast(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  assertEquals(sampleList.getLast().data.intValue(),labRats-1);
 }
 
 public void testRemoveAtFirst(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  int returnValue = sampleList.removeAtFirst();
  assertEquals(returnValue,0);
  assertEquals(sampleList.getFirst().data.intValue(),1);
 }
 
 public void testRemoveAtLast(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  int returnValue = sampleList.removeAtLast();
  assertEquals(returnValue,labRats-1);
  assertEquals(sampleList.getLast().data.intValue(),labRats-2);
 }
 
 public void testRemoveAt(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  int returnValue = sampleList.removeAt(4);
  assertEquals(returnValue,4);
  assertEquals(sampleList.getNodeAt(4).data.intValue(),5);
 }
 
 public void testToString(){
  SinglyLinkedList<Integer> sampleList = getLabRatList(labRats);
  assertEquals(sampleList.toString(),"0, 1, 2, 3, 4, 5, 6, 7, 8, 9");
 }
 
 private SinglyLinkedList<Integer> getLabRatList(int count){
  SinglyLinkedList<Integer> sampleList = new SinglyLinkedList<Integer>();
  for(int i=0;i<count;i++){
   sampleList.add(i);
  }
  return sampleList;
 }
}


Cheers,
Bragaadeesh.