Related
I'm using a generic linked list to implement priority queue where I use the comparable function for the insert function where it finds a slot where it's size is bigger than the current node. I have problem actually getting the add function insert the elements according priority queue requirements. The priority queue should go from smallest to biggest.
Edit: I realize the problem lies with inserting a number bigger than the head. During add 11, the function only compares with 5 and add it after 5 which ruins the sequence.
Current output
PQ: 5
PQ: 5,10
PQ: 5,9,10
PQ: 5,11,9,10
PQ: 5,7,11,9,10
PQ: 2,5,7,11,9,10
Desired output
PQ: 2,5,7,9,10,11
My add function
public class PQLinkedList<T extends Comparable<T>>{
private class Node{
private T data;
private Node next;
// Constructor that takes in data to input for the node
public Node(T data) {
this.data = data;
this.next = null;
}
}
private int length = 0;
private Node head;
int cmp = 0;
public PQLinkedList() {
head = null;
}
//Compare with each element till it finds a suitable position to insert itself
//Ascending order
//INCOMPLETE
//Compare part of this code is not complete!
public void addPQ( T data) {
Node node = new Node(data);
Node temp2 = null;
if ( head == null) {
addFirst(data);
}
else {
Node curr = head;
int count = getSize();
while ( count != 0) {
cmp = data.compareTo(curr.data);
if ( cmp < 0 ) {
addFirst(data);
break;
}
else if (cmp>=0 ){
if ( curr.next == null) {
curr.next = node;
break;
}
// if there curr.next is not empty
// Move all the nodes towards to tail by 1
else {
// after = one space after pos
// PROBLEM
temp2 = curr.next;
Node after = curr.next;
while( after != null) {
after = after.next;
}
node.next = temp2;
curr.next = node;
break;
}
}
else {
curr = curr.next;
}
count--;
}
}
length++;
}
private void addFirst(T data) {
Node node = new Node(data);
if ( head == null ) {
head = node;
}
else {
Node temp = head;
head = node;
node.next = temp;
}
length++;
}
//TO-DO
public void remove( T data) {
if ( !search(data)) {
System.out.println("Linked list does not contain that element!");
return;
}
else if ( head.data == data) {
head = head.next;
}
else {
// If curr is the node to be deleted.
// link from previous node to curr, link from curr to next node
//Traverse through the linkedlist till it finds the node to be deleted and skip it
Node curr = head;
while ( curr != null & curr.next != null ) {
if ( curr.next.data == data) {
//Check if the node 2 next after curr is null
//if so, remove curr.next which contains the value that we want to delete
if ( curr.next.next != null) {
curr.next = curr.next.next;
}
//curr.next.next is null so just curr.next which contains the value we want to delete
else {
curr.next = null;
}
}
//Traverse the curr node
else {
curr = curr.next;
}
}
length--;
}
}
// Retrieves and removes the head of the priority queue
public T poll() {
if ( isEmpty()) {
System.out.println("Linked list is empty!");
return null;
}
else {
Node temp = null;
temp = head ;
head = head.next;
length--;
return temp.data;
}
}
// Retrieves the head of the priority queue
public T peek() {
if ( isEmpty()) {
System.out.println("Linked list is empty!");
return null;
}
else {
return head.data;
}
}
public void clear() {
Node curr = head;
while ( curr != null) {
curr = curr.next;
}
}
public int getSize() {
return length;
}
public boolean search(T data) {
if ( isEmpty()) {
System.out.println("Linked list is empty!");
return false;
}
else {
Node node = head;
while ( node != null ) {
if ( node.data == data) {
return true;
}
node = node.next;
}
return false;
}
}
public boolean isEmpty() {
if ( length == 0) {
return true;
}
return false;
}
#Override
public String toString() {
String str = "PQ: ";
Node node = head;
while ( node != null) {
str = str + node.data;
if ( node.next != null) {
str = str + ",";
}
node = node.next;
}
return str;
}
}
My main
public class priorityQueueImplementation {
public static void main(String[] args) {
PQLinkedList<Integer> test = new PQLinkedList<Integer>();
test.add(5);
test.add(10);
test.add(9);
test.add(11);
test.add(7);
test.add(2);
System.out.println( test.toString());
}
}
Since this is a singly linked list, we cannot add node to previous node. We can only add to subsequent node. During node insertion, we need to compare data with the list. One every node, there are 5 cases:
current is null, data become the new head
data is smaller than current, data become the new head
data is greater than current, data is smaller then next. Insert data between current and next
data is greater than current, next is null. Insert data after current
data is greater than current, data is greater then next. Wait for next iteration
public void addPQ(T data) {
Node node = new Node(data);
Node curr = head;
if (head == null) {
// current is null, data become the new head
addFirst(data);
} else {
while (curr != null) {
int cmpLeft = data.compareTo(curr.data);
if (cmpLeft < 0) {
// data is smaller than current, `data` become the new head
addFirst(data);
break;
} else {
// data is greater than current
if (curr.next == null) {
// next is null. Insert `data` after `current`
addAfter(curr, node);
break;
} else {
int cmpRight = data.compareTo(curr.next.data);
if (cmpRight < 0) {
// data is smaller then next. Insert data between current and next
addAfter(curr, node);
break;
}
}
// data is greater then next. Wait for next iteration
curr = curr.next;
}
}
}
}
private void addAfter(Node currNode, Node newNode) {
if (currNode == null) {
currNode = newNode;
} else {
Node tempTail = currNode.next;
currNode.next = newNode;
newNode.next = tempTail;
}
length++;
}
output
PQ: 2,5,7,9,10,11
I m beginner at java. I am trying to implement simple linklist structure using java.
I have written following code that inserts node at the end of the linklist.
public static Node insert(Node head,int data) {
if(head == null)
{
Node temp = new Node(data);
head = temp;
return head;
}
else
{
Node temp = new Node(data);
Node current = head;
while(current != null)
{
current = current.next;
}
current = temp;
return head;
}
}
The Node class is defined as follows
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
The class LinkListDemo has the insert(),display() and main() method as follows..
class LinkListDemo
{
public static Node insert(Node head,int data) {
if(head == null)
{
Node temp = new Node(data);
head = temp;
return head;
}
else
{
Node temp = new Node(data);
Node current = head;
while(current != null)
{
current = current.next;
}
current = temp;
return head;
}
}
public static void display(Node head) {
Node start = head;
while(start != null) {
System.out.print(start.data + " ");
start = start.next;
}
}
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
Node head = null;
int N = sc.nextInt();
while(N-- > 0) {
int ele = sc.nextInt();
head = insert(head,ele);
}
display(head);
sc.close();
}
}
INPUT: 4 2 3 4 1
I gave input as 4(number of nodes to be inserted) 2 3 4 1(corresponding node values)
I expected output to be 2 3 4 1
but the output is only 2.
Please help me to correct my mistake. Thanks in advance.
The problem is in the else part of your insert method. You are looping till current becomes null and then assign the new node temp to it. Assigning the reference to the new node(temp) will not append (or link) to the end of the list.
The correct way is to go to the last node and then link the new node i.e, make the last node's next point to the new node.
It should be like
while(current.next != null) {
current = current.next;
}
current.next = temp;
In your code for insert(), you should have
while(current.next != null)
{
current = current.next;
}
In your code, your current variable will always end up being null, resulting in your node not actually being inserted. This fix makes your current variable the last node in the list, so that you can set the last node's pointer to your new node.
I am inserting node using following code
public void addFirst(int e) {
if (head == null) {
head = new LinkListNode(e);
tail = head;
size = 1;
} else {
LinkListNode nextNode = new LinkListNode(e);
nextNode.setNext(head);
head = nextNode;
size++;
}
}
Working fine...
Just Change little bit code
Node current = head;
while(current.next != null)
{
current = current.next;
}
current.next= temp;
and return head
This question already has answers here:
How to reverse a singly-linked list in blocks of some given size in O(n) time in place?
(4 answers)
Closed 4 years ago.
Can someone tell me why my code dosent work? I want to reverse a single linked list in java: This is the method (that doesnt work correctly)
public void reverseList(){
Node before = null;
Node tmp = head;
Node next = tmp.next;
while(tmp != null){
if(next == null)
return;
tmp.next = before;
before = tmp;
tmp = next;
next = next.next;
}
}
And this is the Node class:
public class Node{
public int data;
public Node next;
public Node(int data, Node next){
this.data = data;
this.next = next;
}
}
On input 4->3->2->1 I got output 4. I debugged it and it sets pointers correctly but still I dont get why it outputs only 4.
Node next = tmp.next;
while(tmp != null){
So what happens when tmp == null?
You almost got it, though.
Node before = null;
Node tmp = head;
while (tmp != null) {
Node next = tmp.next;
tmp.next = before;
before = tmp;
tmp = next;
}
head = before;
Or in nicer (?) naming:
Node reversedPart = null;
Node current = head;
while (current != null) {
Node next = current.next;
current.next = reversedPart;
reversedPart = current;
current = next;
}
head = reversedPart;
ASCII art:
<__<__<__ __ : reversedPart : head
(__)__ __ __
head : current: > > >
public Node<E> reverseList(Node<E> node) {
if (node == null || node.next == null) {
return node;
}
Node<E> currentNode = node;
Node<E> previousNode = null;
Node<E> nextNode = null;
while (currentNode != null) {
nextNode = currentNode.next;
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
return previousNode;
}
The method for reversing a linked list is as below;
Reverse Method
public void reverseList() {
Node<E> curr = head;
Node<E> pre = null;
Node<E> incoming = null;
while(curr != null) {
incoming = curr.next; // store incoming item
curr.next = pre; // swap nodes
pre = curr; // increment also pre
curr = incoming; // increment current
}
head = pre; // pre is the latest item where
// curr is null
}
Three references are needed to reverse a list: pre, curr, incoming
... pre curr incoming
... --> (n-1) --> (n) --> (n+1) --> ...
To reverse a node, you have to store previous element, so that you can use the simple stament;
curr.next = pre;
To reverse the current element's direction. However, to iterate over the list, you have to store incoming element before the execution of the statement above because as reversing the current element's next reference, you don't know the incoming element anymore, that's why a third reference needed.
The demo code is as below;
LinkedList Sample Class
public class LinkedList<E> {
protected Node<E> head;
public LinkedList() {
head = null;
}
public LinkedList(E[] list) {
this();
addAll(list);
}
public void addAll(E[] list) {
for(int i = 0; i < list.length; i++)
add(list[i]);
}
public void add(E e) {
if(head == null)
head = new Node<E>(e);
else {
Node<E> temp = head;
while(temp.next != null)
temp = temp.next;
temp.next = new Node<E>(e);
}
}
public void reverseList() {
Node<E> curr = head;
Node<E> pre = null;
Node<E> incoming = null;
while(curr != null) {
incoming = curr.next; // store incoming item
curr.next = pre; // swap nodes
pre = curr; // increment also pre
curr = incoming; // increment current
}
head = pre; // pre is the latest item where
// curr is null
}
public void printList() {
Node<E> temp = head;
System.out.print("List: ");
while(temp != null) {
System.out.print(temp + " ");
temp = temp.next;
}
System.out.println();
}
public static class Node<E> {
protected E e;
protected Node<E> next;
public Node(E e) {
this.e = e;
this.next = null;
}
#Override
public String toString() {
return e.toString();
}
}
}
Test Code
public class ReverseLinkedList {
public static void main(String[] args) {
Integer[] list = { 4, 3, 2, 1 };
LinkedList<Integer> linkedList = new LinkedList<Integer>(list);
linkedList.printList();
linkedList.reverseList();
linkedList.printList();
}
}
Output
List: 4 3 2 1
List: 1 2 3 4
If this isn't homework and you are doing this "manually" on purpose, then I would recommend using
Collections.reverse(list);
Collections.reverse() returns void, and your list is reversed after the call.
We can have three nodes previous,current and next.
public void reverseLinkedlist()
{
/*
* Have three nodes i.e previousNode,currentNode and nextNode
When currentNode is starting node, then previousNode will be null
Assign currentNode.next to previousNode to reverse the link.
In each iteration move currentNode and previousNode by 1 node.
*/
Node previousNode = null;
Node currentNode = head;
while (currentNode != null)
{
Node nextNode = currentNode.next;
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
head = previousNode;
}
public void reverse() {
Node prev = null; Node current = head; Node next = current.next;
while(current.next != null) {
current.next = prev;
prev = current;
current = next;
next = current.next;
}
current.next = prev;
head = current;
}
// Java program for reversing the linked list
class LinkedList {
static Node head;
static class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
// Function to reverse the linked list
Node reverse(Node node) {
Node prev = null;
Node current = node;
Node next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
node = prev;
return node;
}
// prints content of double linked list
void printList(Node node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.head = new Node(85);
list.head.next = new Node(15);
list.head.next.next = new Node(4);
list.head.next.next.next = new Node(20);
System.out.println("Given Linked list");
list.printList(head);
head = list.reverse(head);
System.out.println("");
System.out.println("Reversed linked list ");
list.printList(head);
}
}
OUTPUT: -
Given Linked list
85 15 4 20
Reversed linked list
20 4 15 85
I know the recursive solution is not the optimal one, but just wanted to add one here:
public class LinkedListDemo {
static class Node {
int val;
Node next;
public Node(int val, Node next) {
this.val = val;
this.next = next;
}
#Override
public String toString() {
return "" + val;
}
}
public static void main(String[] args) {
Node n = new Node(1, new Node(2, new Node(3, new Node(20, null))));
display(n);
n = reverse(n);
display(n);
}
static Node reverse(Node n) {
Node tail = n;
while (tail.next != null) {
tail = tail.next;
}
reverseHelper(n);
return (tail);
}
static Node reverseHelper(Node n) {
if (n.next != null) {
Node reverse = reverseHelper(n.next);
reverse.next = n;
n.next = null;
return (n);
}
return (n);
}
static void display(Node n) {
for (; n != null; n = n.next) {
System.out.println(n);
}
}
}
I don't get it... why not doing this :
private LinkedList reverseLinkedList(LinkedList originalList){
LinkedList reversedList = new LinkedList<>();
for(int i=0 ; i<originalList.size() ; i++){
reversedList.add(0, originalList.get(i));
}
return reversedList;
}
I find this easier.
A more elegant solution would be to use recursion
void ReverseList(ListNode current, ListNode previous) {
if(current.Next != null)
{
ReverseList(current.Next, current);
ListNode temp = current.Next;
temp.Next = current;
current.Next = previous;
}
}
I tried the below code and it works fine:
Node head = firstNode;
Node current = head;
while(current != null && current.next != null){
Node temp = current.next;
current.next = temp.next;
temp.next = head;
head = temp;
}
Basically one by one it sets the next pointer of one node to its next to next node, so from next onwards all nodes are attached at the back of the list.
Node reverse_rec(Node start) {
if (start == null || start -> next == null) {
return start;
}
Node new_start = reverse(start->next);
start->next->next = start;
start->next = null;
return new_start;
}
Node reverse(Node start) {
Node cur = start;
Node bef = null;
while (cur != null) {
Node nex = cur.next;
cur.next = bef;
bef = cur;
cur = nex;
}
return bef;
}
I think your problem is that your initially last element next attribute isn't being changed becuase of your condition
if(next == null)
return;
Is at the beginning of your loop.
I would move it right after tmp.next has been assigned:
while(tmp != null){
tmp.next = before;
if(next == null)
return;
before = tmp;
tmp = next;
next = next.next;
}
Use this.
if (current== null || current.next==null) return current;
Node nextItem = current.next;
current.next = null;
Node reverseRest = reverse(nextItem);
nextItem.next = current;
return reverseRest
or Java Program to reverse a Singly Linked List
package com.three;
public class Link {
int a;
Link Next;
public Link(int i){
a=i;
}
}
public class LinkList {
Link First = null;
public void insertFirst(int a){
Link objLink = new Link(a);
objLink.Next=First;
First = objLink;
}
public void displayLink(){
Link current = First;
while(current!=null){
System.out.println(current.a);
current = current.Next;
}
}
public void ReverseLink(){
Link current = First;
Link Previous = null;
Link temp = null;
while(current!=null){
if(current==First)
temp = current.Next;
else
temp=current.Next;
if(temp==null){
First = current;
//return;
}
current.Next=Previous;
Previous=current;
//System.out.println(Previous);
current = temp;
}
}
public static void main(String args[]){
LinkList objLinkList = new LinkList();
objLinkList.insertFirst(1);
objLinkList.insertFirst(2);
objLinkList.insertFirst(3);
objLinkList.insertFirst(4);
objLinkList.insertFirst(5);
objLinkList.insertFirst(6);
objLinkList.insertFirst(7);
objLinkList.insertFirst(8);
objLinkList.displayLink();
System.out.println("-----------------------------");
objLinkList.ReverseLink();
objLinkList.displayLink();
}
}
You can also try this
LinkedListNode pointer = head;
LinkedListNode prev = null, curr = null;
/* Pointer variable loops through the LL */
while(pointer != null)
{
/* Proceed the pointer variable. Before that, store the current pointer. */
curr = pointer; //
pointer = pointer.next;
/* Reverse the link */
curr.next = prev;
/* Current becomes previous for the next iteration */
prev = curr;
}
System.out.println(prev.printForward());
package LinkedList;
import java.util.LinkedList;
public class LinkedListNode {
private int value;
private LinkedListNode next = null;
public LinkedListNode(int i) {
this.value = i;
}
public LinkedListNode addNode(int i) {
this.next = new LinkedListNode(i);
return next;
}
public LinkedListNode getNext() {
return next;
}
#Override
public String toString() {
String restElement = value+"->";
LinkedListNode newNext = getNext();
while(newNext != null)
{restElement = restElement + newNext.value + "->";
newNext = newNext.getNext();}
restElement = restElement +newNext;
return restElement;
}
public static void main(String[] args) {
LinkedListNode headnode = new LinkedListNode(1);
headnode.addNode(2).addNode(3).addNode(4).addNode(5).addNode(6);
System.out.println(headnode);
headnode = reverse(null,headnode,headnode.getNext());
System.out.println(headnode);
}
private static LinkedListNode reverse(LinkedListNode prev, LinkedListNode current, LinkedListNode next) {
current.setNext(prev);
if(next == null)
return current;
return reverse(current,next,next.getNext());
}
private void setNext(LinkedListNode prev) {
this.next = prev;
}
}
public class ReverseLinkedList {
public static void main(String args[]){
LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("a");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
linkedList.add("e");
linkedList.add("f");
System.out.println("Original linkedList:");
for(int i = 0; i <=linkedList.size()-1; i++){
System.out.println(" - "+ linkedList.get(i));
}
LinkedList<String> reversedlinkedList = reverse(linkedList);
System.out.println("Reversed linkedList:");
for(int i = 0; i <=reversedlinkedList.size()-1; i++){
System.out.println(" - "+ reversedlinkedList.get(i));
}
}
public static LinkedList<String> reverse(LinkedList<String> linkedList){
for(int i = 0; i < linkedList.size()/2; i++){
String temp = linkedList.get(i);
linkedList.set(i, linkedList.get(linkedList.size()-1-i));
linkedList.set((linkedList.size()-1-i), temp);
}
return linkedList;
}
}
To reverse a singly linked list you should have three nodes, top, beforeTop and AfterTop. Top is the header of singly linked list, hence beforeTop would be null and afterTop would be next element of top and with each iteration move forward beforeTop is assigned top and top is assigned afterTop(i.e. top.next).
private static Node inverse(Node top) {
Node beforeTop=null, afterTop;
while(top!=null){
afterTop=top.next;
top.next=beforeTop;
beforeTop=top;
top=afterTop;
}
return beforeTop;
}
Using Recursion It's too easy :
package com.config;
import java.util.Scanner;
public class Help {
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
Node head = null;
Node temp = null;
int choice = 0;
boolean flage = true;
do{
Node node = new Node();
System.out.println("Enter Node");
node.data = sc.nextInt();
if(flage){
head = node;
flage = false;
}
if(temp!=null)
temp.next = node;
temp = node;
System.out.println("Enter 0 to exit.");
choice = sc.nextInt();
}while(choice!=0);
Help.getAll(head);
Node reverse = Help.reverse(head,null);
//reverse = Help.reverse(head, null);
Help.getAll(reverse);
}
public static void getAll(Node head){
if(head==null)
return ;
System.out.println(head.data+"Memory Add "+head.hashCode());
getAll(head.next);
}
public static Node reverse(Node head,Node tail){
Node next = head.next;
head.next = tail;
return (next!=null? reverse(next,head) : head);
}
}
class Node{
int data = 0;
Node next = null;
}
Node Reverse(Node head) {
Node n,rev;
rev = new Node();
rev.data = head.data;
rev.next = null;
while(head.next != null){
n = new Node();
head = head.next;
n.data = head.data;
n.next = rev;
rev = n;
n=null;
}
return rev;
}
Use above function to reverse single linked list.
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
check more details about complexity analysis
http://javamicro.com/ref-card/DS-Algo/How-to-Reverse-Singly-Linked-List?
public static LinkedList reverseLinkedList(LinkedList node) {
if (node == null || node.getNext() == null) {
return node;
}
LinkedList remaining = reverseLinkedList(node.getNext());
node.getNext().setNext(node);
node.setNext(null);
return remaining;
}
/**
* Reverse LinkedList
* #author asharda
*
*/
class Node
{
int data;
Node next;
Node(int data)
{
this.data=data;
}
}
public class ReverseLinkedList {
static Node root;
Node temp=null;
public void insert(int data)
{
if(root==null)
{
root=new Node(data);
}
else
{
temp=root;
while(temp.next!=null)
{
temp=temp.next;
}
Node newNode=new Node(data);
temp.next=newNode;
}
}//end of insert
public void display(Node head)
{
while(head!=null)
{
System.out.println(head.data);
head=head.next;
}
}
public Node reverseLinkedList(Node head)
{
Node newNode;
Node tempr=null;
while(head!=null)
{
newNode=new Node(head.data);
newNode.next=tempr;
tempr=newNode;
head=head.next;
}
return tempr;
}
public static void main(String[] args) {
ReverseLinkedList r=new ReverseLinkedList();
r.insert(10);
r.insert(20);
r.insert(30);
r.display(root);
Node t=r.reverseLinkedList(root);
r.display(t);
}
}
public class SinglyLinkedListImpl<T> {
private Node<T> head;
public void add(T element) {
Node<T> item = new Node<T>(element);
if (head == null) {
head = item;
} else {
Node<T> temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = item;
}
}
private void reverse() {
Node<T> temp = null;
Node<T> next = null;
while (head != null) {
next = head.next;
head.next = temp;
temp = head;
head = next;
}
head = temp;
}
void printList(Node<T> node) {
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
System.out.println();
}
public static void main(String a[]) {
SinglyLinkedListImpl<Integer> sl = new SinglyLinkedListImpl<Integer>();
sl.add(1);
sl.add(2);
sl.add(3);
sl.add(4);
sl.printList(sl.head);
sl.reverse();
sl.printList(sl.head);
}
static class Node<T> {
private T data;
private Node<T> next;
public Node(T data) {
super();
this.data = data;
}
}
}
public class Linkedtest {
public static void reverse(List<Object> list) {
int lenght = list.size();
for (int i = 0; i < lenght / 2; i++) {
Object as = list.get(i);
list.set(i, list.get(lenght - 1 - i));
list.set(lenght - 1 - i, as);
}
}
public static void main(String[] args) {
LinkedList<Object> st = new LinkedList<Object>();
st.add(1);
st.add(2);
st.add(3);
st.add(4);
st.add(5);
Linkedtest.reverse(st);
System.out.println("Reverse Value will be:"+st);
}
}
This will be useful for any type of collection Object.
I searched on the net for a good clean and simple implentation of a merge sort algorithm in Java for a Linked List that uses recursion.
I couldn't find a nice one so Im trying to implement it here. but Im stuck.
Here is what I have so far:
public List mergeSortList(Node head, Node tail) {
if ((head == null) || (head.next == null))
return;
Node middle = this.findMiddle(head);
List left = mergeSortList(this.head, middle);
List right = mergeSortList(middle.next, tail);
return merge(left, right);
}
private List merge(List left, List right) {
List returnedList = new LinkedList();
}
private Node findMiddle(Node n) {
Node slow, fast;
slow = fast = n;
while (fast != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
Can someone help me correct any errors and fill the stubs please.
Thanks
First error is in following :-
while(fast != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
}
fast.next can be null when you do fast.next.next , considering the case when no of elements is odd.
Here is a modified code:-
while(fast != null && fast.next.next != null)
{
slow = slow.next;
if(fast.next!=null)
fast = fast.next.next;
else break;
}
Here is another modification:-
public List mergeSortList(Node head)
{
if ( (head == null) || (head.next == null))
return head;
Node middle = this.findMiddle(head);
Node first = head;
Node second = middle.next;
middle.next = null;
Node left = mergeSortList(first);
Node right = mergeSortList(second);
return merge(left, right);
}
Explanation: You donot need to pass tail to the function, You can split the list at middle into two separate list ending with null. And after recursion of two list just reconnect them to prevent loss of original list
Here is clean and simple implementation for Merge Sort on LinkedList
public class MergeSortLinkedList {
static class Node {
Node next;
int value;
Node(int value) {
this.value = value;
}
}
public static void main(String[] args) {
Node head = new Node(10);
head.next = new Node(5);
head.next.next = new Node(2);
head.next.next.next = new Node(1);
head.next.next.next.next = new Node(6);
head.next.next.next.next.next = new Node(8);
head.next.next.next.next.next.next = new Node(3);
head.next.next.next.next.next.next.next = new Node(2);
print(head);
Node sortedHead = mergeSort(head);
print(sortedHead);
}
static void print(Node head) {
Node tmp = head;
while (tmp != null) {
System.out.print(tmp.value + "->");
tmp = tmp.next;
}
System.out.println();
}
static Node getMiddle(Node head) {
if (head == null || head.next == null) {
return head;
}
Node slow = head;
Node fast = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
static Node sortedMerge(Node left, Node right) {
if (left == null) {
return right;
}
if (right == null) {
return left;
}
if (left.value < right.value) {
left.next = sortedMerge(left.next, right);
return left;
} else {
right.next = sortedMerge(left, right.next);
return right;
}
}
static Node mergeSort(Node head) {
if (head == null || head.next == null) {
return head;
}
Node middle = getMiddle(head);
Node middleNext = middle.next;
middle.next = null;
Node left = mergeSort(head);
Node right = mergeSort(middleNext);
return sortedMerge(left, right);
}
}
This looks like a good start. Your merge method is going to work just like any other merge sort implementation except you're dealing with lists instead of integers.
What you need to do is:
create a new list to return ('result')
compare the first element in List 'left' to the first in List 'right'
copy the smaller element to the result
advance your pointer into whichever list the smaller element came from
repeat until you hit the end of a list
copy all the remaining elements to the result
Take a stab at that (post your updated code) and we'll be happy to help you out more from there.
Solution divided in two methods,
First method is recursive method what we call from main(), then divide list using fast and slow pointer technique (fast walks 2 step when slow walks one), now call itself recursively with both the lists, and combine returned list using second method mergeSortedList, also we are calling mergeSortedList again and again within the recursion, so at the very end when there is only one element left in each list, we compare them and add together in right order.
ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode fast = head;
ListNode slow = head;
// get in middle of the list :
while (fast.next!= null && fast.next.next !=null){slow = slow.next; fast = fast.next.next;}
fast = slow.next;
slow.next=null;
return mergeSortedList(sortList(head),sortList(fast));
}
ListNode mergeSortedList(ListNode firstList,ListNode secondList){
ListNode returnNode = new ListNode(0);
ListNode trackingPointer = returnNode;
while(firstList!=null && secondList!=null){
if(firstList.val < secondList.val){trackingPointer.next = firstList; firstList=firstList.next;}
else {trackingPointer.next = secondList; secondList=secondList.next;}
trackingPointer = trackingPointer.next;
}
if (firstList!=null) trackingPointer.next = firstList;
else if (secondList!=null) trackingPointer.next = secondList;
return returnNode.next;
}
}
Working solution in java. Go to the link below:
http://ideone.com/4WVYHc
import java.util.*;
import java.lang.*;
import java.io.*;
class Node
{
int data;
Node next;
Node(int data){
this.data = data;
next = null;
}
void append(Node head, int val){
Node temp = new Node(val);
Node cur = head;
if(head == null)
{
return;
}
while(cur.next != null)
{
cur = cur.next;
}
cur.next = temp;
return;
}
void display(){
Node cur = this;
while(cur != null)
{
System.out.print(cur.data + "->");
cur = cur.next;
}
}
}
class Ideone
{
public Node findMiddle(Node head){
if(head == null )
return null;
Node slow, fast;
slow = head;
fast = head;
while(fast != null && fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public Node merge(Node first, Node second){
Node head = null;
while(first != null && second != null){
if(first.data < second.data){
if(head == null){
head = new Node(first.data);
}
else
head.append(head,first.data);
first = first.next;
}
else if(second.data < first.data){
if(head == null){
head = new Node(second.data);
}
else
head.append(head,second.data);
second = second.next;
}
else{
if(head == null){
head = new Node(first.data);
head.append(head,second.data);
}
else{
head.append(head,first.data);
head.append(head,second.data);
}
second = second.next;
first = first.next;
}
}
while(first != null){
if(head == null){
head = new Node(first.data);
}
else
head.append(head,first.data);
first = first.next;
}
while(first != null){
if(head == null){
head = new Node(first.data);
}
else
head.append(head,first.data);
first = first.next;
}
while(second != null){
if(head == null){
head = new Node(second.data);
}
else
head.append(head,second.data);
second = second.next;
}
return head;
}
public Node mergeSort(Node head){
if(head == null)
return null;
if(head.next == null)
return head;
Node first = head;
Node mid = findMiddle(first);
Node second = mid.next;
mid.next = null;
Node left = mergeSort(first);
Node right = mergeSort(second);
Node result = merge(left, right);
return result;
}
public static void main (String[] args) throws java.lang.Exception
{
Node head = new Node(5);
head.append(head,1);
head.append(head,5);
head.append(head,1);
head.append(head,5);
head.append(head,3);
System.out.println("Unsoreted linked list:");
head.display();
Ideone tmp = new Ideone();
Node result = tmp.mergeSort(head);
System.out.println("\nSorted linked list:");
result.display();
}
}
Below is the Java version of the post to sort numbers in linked list using merge sort.
import java.util.ArrayList;
public class SortNumbersInLinkedListUsingMergeSort {
Node head;
public static void main(String[] args) {
SortNumbersInLinkedListUsingMergeSort sll = new SortNumbersInLinkedListUsingMergeSort();
// creating an unsorted linked list
sll.head = new Node(2);
sll.head.next = new Node(5);
sll.head.next.next = new Node(3);
sll.head.next.next.next = new Node(-1);
sll.head.next.next.next.next = new Node(1);
printList(sll.head);
sll.head = Merge(sll.head);
printList(sll.head);
}
//
public static Node Merge(Node head){
// if linked list has no or only one element then return
if (head == null || head.next == null){
return null;
}
// split the linked list into two halves, (front and back as two heads)
ArrayList<Node> list = splitIntoSublists(head);
// Recursively sort the sub linked lists
Merge(list.get(0));
Merge(list.get(1));
// merge two sorted sub lists
head = mergeTwoSortedLists(list.get(0), list.get(1));
return head;
}
// method to merge two sorted linked lists
public static Node mergeTwoSortedLists(Node front, Node back){
Node result;
if (front == null){
return back;
}
if (back == null){
return front;
}
if (front.data >= back.data){
result = back;
result.next = mergeTwoSortedLists(front, back.next);
}
else{
result = front;
result.next = mergeTwoSortedLists(front.next, back);
}
return result;
}
// method to split linked list into two list in middle.
public static ArrayList<Node> splitIntoSublists(Node head){
Node slowPointer;
Node fastPointer ;
Node front = null;
Node back = null;
ArrayList<Node> li = new ArrayList<Node>();
if (head == null || head.next == null){
front = head;
back = null;
}
else{
slowPointer= head;
fastPointer = head.next;
while (fastPointer != null && fastPointer.next != null){
slowPointer = slowPointer.next;
fastPointer = fastPointer.next.next;
}
front = head;
back = slowPointer.next;
slowPointer.next = null;
}
li.add(front);
li.add(back);
return li;
}
// method to print linked list
public static void printList(Node head){
Node pointer = head;
while (pointer != null){
System.out.print(pointer.data + " ");
pointer = pointer.next;
}
System.out.println();
}
}
// class to define linked list
class Node{
int data;
Node next;
public Node (int data){
this.data = data;
}
}
Here is a working example :
public class MergeSort{
public Node head = null;
public class Node {
int val;
Node next;
public Node () {//Constructor
val = 0;
next = null;
}
public Node (int i) { //constructor
val = i;
next = null;
}
}
public void insert ( int i) { //inserts node at the beginning
Node n = new Node(i);
n.next = head;
head = n;
}
public void printList (Node head) {
while (head != null) {
System.out.println (head.val);
head = head.next;
}
}
public Node sort (Node head) {
if ( head == null || head.next ==null ) return head; // no need to sort if there's no node or only one node in the Linked List
Node mid = find_Mid (head); // find middle of the LinkedList
Node sHalf = mid.next ; mid.next = null; //Splitting into two linked lists
Node h = merge ( sort(head), sort(sHalf) ); //Call merge recursively
return h;
}
public Node merge ( Node n1 , Node n2) {
Node curr = null;
if ( n1 == null )
return n2; //n1 empty
if ( n2 == null )
return n1; // n2 empty
if ( n1.val < n2.val ) {
curr=n1;
curr.next = merge (n1.next, n2); //Call merge recursively
}
else {
curr = n2;
curr.next = merge (n1, n2.next); //Call merge recursively
}
return curr;
}
public Node find_Mid (Node head) {
Node slow = head; Node fast = head;
while ( fast.next != null && fast.next.next != null ) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public static void main(String []args){
System.out.println("Hello World");
MergeSort m = new MergeSort ();
m.insert ( 3 );
m.insert ( 4 );
m.insert ( 16 );
m.insert ( 10 );
m.insert ( 5 );
m.insert ( 1 );
m.insert ( -5 );
m.printList(m.head);
Node n = m.find_Mid (m.head);
System.out.println("Middle is :" + n.val);
m.head = m.sort(m.head);
m.printList(m.head);
}
}
Data structures class, implementing a singly linked-list with head, tail and current nodes. Having trouble with a method, could use a nudge in the right direction.
From the assignment, write the method:
add( item ) : adds the item (String) after the current node in the list and sets the current pointer to refer to the new node.
My attempt:
public void add(String item)
{
if(curr != null)
{
Node newNode = new Node(item, curr.next);
curr.next = newNode;
curr = newNode;
}
else
{
head = tail = new Node(item, null);
curr = head;
}
}
My add method only seems to work when I'm adding items to the middle of the list, not on either end. If I use it to add a few items and then print the list, only the first one I added will be on the list, while my prepend and append methods have tested just fine.
Is there any glaring issue with my code? I feel like I'm missing something obvious.
All:
public class LinkedList {
Node head = null; /* Head of the list */
Node tail = null; /* Tail of the list */
Node curr = null; /* Current node in the list */
public void prepend(String item) {
if (head == null) {
head = tail = new Node(item, null);
curr = head;
} else {
head = new Node(item, head);
curr = head;
}
}
public void append(String item) {
if (head == null) {
head = tail = new Node(item, null);
curr = tail;
} else {
tail.next = new Node(item, null);
tail = tail.next;
curr = tail;
}
}
public void add(String item) {
if (curr != null) {
Node newNode = new Node(item, curr.next);
curr.next = newNode;
curr = newNode;
} else {
head = tail = new Node(item, null);
curr = head;
}
}
public void delete() {
if (curr.next == null) {
Node temp = head;
while (temp.next != curr) {
System.out.println(temp.item);
temp = temp.next;
}
temp.next = null;
curr = head;
}
}
public void find(String item) {
Node temp = new Node(curr.item, curr.next);
if (item.equals(temp.item))
curr = temp;
else {
temp = temp.next;
while (temp.next != null && temp != curr) {
if (item.equals(temp.item))
curr = temp;
}
}
}
public String get() {
if (curr != null)
return curr.item;
else
return "";
}
public boolean next() {
if (curr != tail) {
curr = curr.next;
return true;
} else
return false;
}
public void start() {
curr = head;
}
public void end() {
curr = tail;
}
public boolean empty() {
if (head == null)
return true;
else
return false;
}
}
Node class:
class Node {
Node next;
String item;
Node(String item, Node next) {
this.next = next;
this.item = item;
}
}
There is indeed a problem in add: it doesn't update tail when nodes already exist. Consider this sequence of actions:
LinkedList list = new LinkedList();
list.add("one");
list.add("two");
list.append("three");
If you were to then print it using this:
public void print() {
Node curr = this.head;
while(curr != null) {
System.out.println(curr.item);
curr = curr.next;
}
}
Like this:
list.print();
You'd get the following output:
one
three
This happens because tail -- which append relies on -- continues to point to the first Node after the second add operation is performed.
I don't see any problems here, so I would guess the issue is elsewhere.
Okay, the only issue I see there is in delete:
public void delete()
{
Node temp = head;
while(temp != null && temp.next != curr) {
System.out.println(temp.item);
temp=temp.next;
}
if (temp != null && temp.next != null) {
temp.next = temp.next.next;
}
curr = head;
}
I think I have found your problem.
If you use append() you add it directly after the tail. But when you have added previous nodes after the tail you don't set your tail to the new node. This means that once you call append() twice you loose all the nodes that you have added after the first append().
Brief example:
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add("First add");
list.append("First Append");
list.add("Second add");
list.prepend("First prepend");
list.add("Third add");
list.prepend("Second prepend");
list.add("fourth add");
list.append("Second Append");
list.add("Fifth add");
list.add("Sixth add");
list.start();
do {
System.out.println(list.get().toString());
} while (list.next());
}
Output:
Second prepend
fourth add
First prepend
Third add
First add
First Append
Second Append
Conclusion: "Second Add" is lost, as well as "Fifth add" and "Sixth add" because your next() method stops as soon as it reaches the tail. You need to always update the tail if you add a new node in the end.
Hope this helps.
Cheers, Chnoch
I think the problem is
if (curr != null) {
Node newNode = new Node(item, curr.next); //<-- here (curr.next)
//and
Node(String item, Node next) {
this.next = next; //<-- here
Try (Edited):
Node newNode = new Node(item, curr); // pass curr to the constructor of Node
curr = newNode;