package com.kartik.linklist;
public class Palindrome<T> {
public static class Node<T> {
// reference to the next node in the chain, or null if there isn't one.
Node<T> next;
// data carried by this node. could be of any type you need.
T data;
// Node constructor
public Node(T dataValue) {
next = null;
data = dataValue;
}
// another Node constructor if we want to specify the node to point to.
public Node(T dataValue, Node<T> nextValue) {
next = nextValue;
data = dataValue;
}
// these methods should be self-explanatory
public T getData() {
return data;
}
public void setData(T dataValue) {
data = dataValue;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> nextValue) {
next = nextValue;
}
}
private Node<T> head;
private Node<T> tail;
/**
* default constructor
*/
public Palindrome() {
}
/**
* Parameter constructor
*
* @param data
*/
Palindrome(T data) {
Node<T> n1 = new Node<T>(data);
this.head = n1;
this.tail = n1;
}
/**
* appends the specified element to the end of this list.
*
* @param data
*/
public void add(T data) {
// if we have an empty list, create a new list
// and copy its head and tail into current object
if (this.head == null) {
Palindrome<T> linkList = (new Palindrome<T>(data));
this.head = linkList.head;
this.tail = linkList.tail;
return;
}
// we need to add this node 'n' to the end of the list
Node<T> n = new Node<T>(data);
Node<T> current = this.head, prev = null;
while (current != null) {
prev = current;
current = current.next;
}
prev.next = n;
this.tail = n; // update the tail info as well
}
public String toString() {
String output = "";
if (head != null) {
Node<T> n = head.getNext();
output += "[" + head.getData().toString() + "]-->";
while (n != null) {
output += "[" + n.getData().toString() + "]-->";
n = n.getNext();
}
}
return output;
}
/**
* <ul>
* <li>The Tortoise (Slow ptr) and the Hare (fast ptr) start at the
* beginning of linked list.</li>
* <li>For each iteration, slow ptr moves one step and the fast ptr moves
* two steps.</li>
* <li>If there is a loop, fast ptr will go around the loop and meet with
* slow ptr.</li>
* <li>If there is no loop, the fast prt will get to the end of the list
* without meeting up with the slow ptr.</li>
* </ul>
*
* @purpose This function will find middle element in linkedlist
* */
public Node<T> findMiddleNode(Node<T> head) {
Node<T> slowPointer, fastPointer;
slowPointer = fastPointer = head;
while (fastPointer != null) {
fastPointer = fastPointer.next;
if (fastPointer != null && fastPointer.next != null) {
slowPointer = slowPointer.next;
fastPointer = fastPointer.next;
}
}
return slowPointer;
}
/**
* <ul>
* <li>First find out the middle node of link list.</li>
* <li>Second from last half to end convert reverse of link list</li>
* <li>Compare the first node and reverse of the last node</li>
* </ul>
*
* @purpose Function to check if linked list is palindrome or not
* @return
*/
public boolean checkPalindrome() {
Node<T> fastPtr = head;
// Find middle node using slow and fast pointer
Node<T> middleNode = findMiddleNode(fastPtr);
// we got head of second part
Node<T> secondHead = middleNode.next;
// It is end of first part of linked list
middleNode.next = null;
// get reversed linked list for second part
Node<T> reverseSecondHead = reverseLinkedList(secondHead);
while (fastPtr != null && reverseSecondHead != null) {
if (fastPtr.data == reverseSecondHead.data) {
fastPtr = fastPtr.next;
reverseSecondHead = reverseSecondHead.next;
continue;
} else {
return false;
}
}
return true;
}
/**
* @purpose This is the function of reverse link list
* @param currentNode
* currentNode
* @return previousNode of Node<T> object
*/
public Node<T> reverseLinkedList(Node<T> currentNode) {
// For first node, previousNode will be null
Node<T> previousNode = null;
Node<T> nextNode;
while (currentNode != null) {
nextNode = currentNode.next;
// reversing the link
currentNode.next = previousNode;
// moving currentNode and previousNode by 1 node
previousNode = currentNode;
currentNode = nextNode;
}
return previousNode;
}
public static void main(String[] args) {
System.out.println("------------------Integer-------------------");
Palindrome<Integer> list = new Palindrome<Integer>();
list.add(5);
list.add(6);
list.add(3);
list.add(3);
list.add(6);
list.add(5);
System.out.println(list.toString());
System.out.println("Linked list palidrome: "+list.checkPalindrome());
System.out.println();
System.out.println("------------------String-------------------");
Palindrome<String> list2 = new Palindrome<String>();
list2.add("Kartik");
list2.add("Mandal");
list2.add("Saharda");
list2.add("kharagpur");
list2.add("Westbengal");
list2.add("India");
list2.add("India");
list2.add("Westbengal");
list2.add("kharagpur");
list2.add("Saharda");
list2.add("Mandal");
list2.add("Kartik");
System.out.println(list2.toString());
System.out.println("Linked list palidrome: "+list2.checkPalindrome());
}
}
Out put:
------------------Integer-------------------
[5]-->[6]-->[3]-->[3]-->[6]-->[5]-->
Linked list palidrome: true
------------------String-------------------
[Kartik]-->[Mandal]-->[Saharda]-->[kharagpur]-->[Westbengal]-->[India]-->[India]-->[Westbengal]-->[kharagpur]-->[Saharda]-->[Mandal]-->[Kartik]-->
Linked list palidrome: true