Showing posts with label linked list. Show all posts
Showing posts with label 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

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.

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.