Reverse even numbers (Only) from given Singly Linked List - java

I want to reverse even numbers in a singly linked list in java, but I face some difficulty to get the correct output.
For example,
input : 2, 18, 24, 3, 5, 7, 9, 6, 12
the method should reverse the even numbers only which are {2,18,24} and {6,12}
the correct output : 24 , 18 ,2 , 3 , 5 ,7 , 9 , 12 , 6
But,my output: 24 18 3 5 7 9 12 6 which it is wrong
the main method
public static void main(String[] args) throws Exception {
SLL<Integer> p = new SLL<Integer>();
int[] e = { 2, 18, 24, 3, 5, 7, 9, 6, 12,5 ,4 ,3 ,2,6,8};
for (int i = 0; i < e.length; i++) {
p.addToHead(e[i]);
}
p = reverse(p);
p.printAll();
}
This is the method (that doesn't work correctly)
public static SLL<Integer> reverse(SLL<Integer> p) {
SLL<Integer> returnList = new SLL<Integer>();
Stack<Integer> stk = new Stack<Integer>();
for (SLLNode tmp = p.getHead(); tmp != null; tmp = tmp.next) {
if ((((Integer) tmp.info) % 2) != 0) {
returnList.addToHead((Integer) tmp.info);
p.deleteFromHead();
} else if ((((Integer) tmp.info) % 2) == 0) {
stk.push((Integer) tmp.info);
p.deleteFromHead();
}
if (stk.getLSize() >= 2) {
while (!(stk.isEmpty())) {
returnList.addToHead((Integer) stk.pop());
}
}
}
return returnList;
}
this is the SLLNode class
public class SLLNode<T> {
public T info;
public SLLNode<T> next;
public SLLNode() {
this(null,null);
}
public SLLNode(T el) {
this(el,null);
}
public SLLNode(T el, SLLNode<T> ptr) {
info = el;
next = ptr;
}
}
this is the SLL class
public class SLL<T> {
protected SLLNode<T> head, tail;
public SLL() {
head = tail = null;
}
public boolean isEmpty() {
return head == null;
}
public void addToHead(T el) {
head = new SLLNode<T>(el, head);
if (tail == null)
tail = head;
}
public SLLNode getHead(){
return head;
}
public void addToTail(T el) {
if (!isEmpty()) {
tail.next = new SLLNode<T>(el);
tail = tail.next;
} else
head = tail = new SLLNode<T>(el);
}
public T deleteFromHead() { // delete the head and return its info;
if (isEmpty())
return null;
T el = head.info;
if (head == tail) // if only one node on the list;
head = tail = null;
else
head = head.next;
return el;
}
public T deleteFromTail() { // delete the tail and return its info;
if (isEmpty())
return null;
T el = tail.info;
if (head == tail) // if only one node in the list;
head = tail = null;
else { // if more than one node in the list,
SLLNode<T> tmp; // find the predecessor of tail;
for (tmp = head; tmp.next != tail; tmp = tmp.next)
;
tail = tmp; // the predecessor of tail becomes tail;
tail.next = null;
}
return el;
}
public void delete(T el) { // delete the node with an element el;
if (!isEmpty())
if (head == tail && el.equals(head.info)) // if only one
head = tail = null; // node on the list;
else if (el.equals(head.info)) // if more than one node on the list;
head = head.next; // and el is in the head node;
else { // if more than one node in the list
SLLNode<T> pred, tmp;// and el is in a nonhead node;
for (pred = head, tmp = head.next; tmp != null
&& !tmp.info.equals(el); pred = pred.next, tmp = tmp.next)
;
if (tmp != null) { // if el was found;
pred.next = tmp.next;
if (tmp == tail) // if el is in the last node;
tail = pred;
}
}
}
public void printAll() {
for (SLLNode<T> tmp = head; tmp != null; tmp = tmp.next)
System.out.print(tmp.info + " ");
}
public boolean isInList(T el) {
SLLNode<T> tmp;
for (tmp = head; tmp != null && !tmp.info.equals(el); tmp = tmp.next)
;
return tmp != null;
}
public int length() {
int length = 0;
for (SLLNode tmp = head; tmp != null; tmp = tmp.next) {
length += 1;
}
return length;
}

Running your reverse method gives me a different output to what you see. So, I suspect you got your output from slightly different code.
I get : 24, 6, 9, 7, 5, 3, 2, 18
In your reverse method you start adding even numbers to your returnList when you have 2 on the stack. If you want to reverse all even numbers you need to wait until you have all the continuous even numbers on the stack. Or in other words, when you get an odd number, or there are no numbers left, you can pop all the even numbers back off the stack..
I think you should also use addTail rather than addHead.
So something like
public static SLL<Integer> reverse(SLL<Integer> p) {
SLL<Integer> returnList = new SLL<Integer>();
Stack<Integer> stk = new Stack<Integer>();
for (SLLNode tmp = p.getHead(); tmp != null; tmp = tmp.next) {
if ((((Integer) tmp.info) % 2) != 0) {
// add any stacked even numbers
while (!(stk.isEmpty())) {
returnList.addToTail((Integer) stk.pop());
}
// add the odd number
returnList.addToTail((Integer) tmp.info);
} else if ((((Integer) tmp.info) % 2) == 0) {
System.out.println("even " + tmp.info);
stk.push((Integer) tmp.info);
}
}
// add any remaining even numbers from the stack
while (!(stk.isEmpty())) {
returnList.addToTail((Integer) stk.pop());
}
return returnList;
}

I made it using list of python, I just wanted to know whether I could write this program without using a linked list or not. The complexities may be high, but it is just an experimental implementation which works
arr = [2,18,24,3,5,7,9,6,12]
arr_final = []
temp = []
for i in arr:
if i%2 == 0:
temp.append(i)
else:
if temp!=[]:
temp.reverse()
for j in temp:
arr_final.append(j)
temp = []
arr_final.append(i)
if temp!=[]:
temp.reverse()
for j in temp:
arr_final.append(j)
temp = []
print(arr_final)

Related

How can I insert an Item at the end of the List?

I am working on a project for my Data Structures class that asks me to write a class to implement a linked list of ints.
Use an inner class for the Node.
Include the methods below.
Write a tester to enable you to test all of the methods with whatever data you want in any order.
I have a method called "public void insertAt(int index, int item)". This method is meant to "Insert an item at position index, where index is passed to the method" I have my code for this method down below. When I insert an Item at an Index it works unless it's the last item in the list. When I try to insert an item at the end of the list it replaces the last item and the item that was there before is erased when It shouldn't. For example, If I had a list: "[9, 8, 15, 7, 5, 15, 19, 6, 19, 2]" and I want to insert the number "90" and the last index it should look like [9, 8, 15, 7, 5, 15, 19, 6, 19, 90, 2] but instead I get [9, 8, 15, 7, 5, 15, 19, 6, 19, 90]. How can I fix this in my code so if I was to insert an item at the tail it would move the Item I want inserted to be placed before the tail?
import java.util.Random;
import java.util.Scanner;
public class LinkedListOfInts {
Node head;
Node tail;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
}
public LinkedListOfInts(LinkedListOfInts other) {
Node tail = null;
for (Node n = other.head; n != null; n = n.nextNode) {
if (tail == null)
this.head = tail = new Node(n.value, null);
else {
tail.nextNode = new Node(n.value, null);
tail = tail.nextNode;
}
}
}
public LinkedListOfInts(int[] other) {
Node[] nodes = new Node[other.length];
for (int index = 0; index < other.length; index++) {
nodes[index] = new Node(other[index], null);
if (index > 0) {
nodes[index - 1].nextNode = nodes[index];
}
}
head = nodes[0];
}
public LinkedListOfInts(int N, int low, int high) {
Random random = new Random();
for (int i = 0; i < N; i++)
this.addToFront(random.nextInt(high - low) + low);
}
public void addToFront(int x) {
head = new Node(x, head);
}
public void insertAt(int index, int item) {
Node temp = head;
Node prev = null;
int i = 0;
for (Node ptr = head; ptr != null; ptr = ptr.nextNode) {
if (index == i) {
Node newItem = new Node(item, null);
prev.nextNode = newItem;
if (temp.nextNode != null) {
newItem.nextNode = temp;
}
}
if (temp.nextNode != null) {
prev = temp;
temp = temp.nextNode;
i++;
}
}
}
public String toString() {
String result = "";
for (Node ptr = head; ptr != null; ptr = ptr.nextNode) {
if (!result.isEmpty()) {
result += ", ";
}
result += ptr.value;
}
return "[" + result + "]";
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
LinkedListOfInts list = new LinkedListOfInts(10, 1, 20);
boolean done = false;
while (!done) {
System.out.println("1. Insert At");
System.out.println("2. toString");
switch (input.nextInt()) {
case 1:
System.out.println("Insert an Item to a certain Index on the List");
list.insertAt(input.nextInt(), input.nextInt());
break;
case 2:
System.out.println("toString");
System.out.println(list.toString());
break;
}
}
}
}
You have an error in this line:
if (temp.nextNode != null) {
newItem.nextNode = temp;
}
Right there, temp is your last element, be it 2. Your new element ( 90) will only have temp assigned, it temp has a pointer to the next element (temp.nextNode != null) Because temp has no next element, nextNode won't be assigned at all. In fact, you can omit this check at all cause if temp was null , you would only assign null to the nextNode of the newItem which would be fine.
Also, make sure to handle other issues in your implementation, such as adding the element at index 0. At the moment, in the beginning you set Node prev = null; and then in the first iteration of the loop prev is null and you would end up with the NPE whenever you try to add the element at index 0.
To fix this, you need to change this section:
if (index == i) {
Node newItem = new Node(item, null);
prev.nextNode = newItem;
newItem.nextNode = temp;
}
into
if (index == i) {
Node newItem = new Node(item, null);
if (prev != null) {
prev.nextNode = newItem;
}
newItem.nextNode = temp;
}
Writing good unit tests may help you with the robust implementation and will help you solve this kind of issues much quicker. Check out this question to see how to write unit tests in java.

Java Doubly Linked List removeLast()

I have a class assignment that required me to create a class DoubleList that implements a ListADT.
I've gotten to the point where the code ALMOST works correctly. The output for the code should be:
1 3 7 9 13 14 16 17 23 24
3 9 13 16
My output is:
1 3 7 9 13 14 16 17 23 24
3 9 13 16 23
The first removeLast() seems to remove the 24 but for some reason the 23 stays after the second removeLast() is called. Please help!
EDIT: If I call removeLast() another time, it removes the 23.
class DoubleList<T> implements ListADT<T>{
private int _size;
private DoubleNode _head;
private DoubleNode _tail;
public DoubleList() {
_size = 0;
_head = null;
_tail = null;
}
public T removeFirst(){
if(_size == 0){
return null;
}
DoubleNode tmp = _head;
_head = _head._next;
_head._previous = null;
_size--;
return tmp._value;
}
public T removeLast(){
if(_size == 0) {
return null;
}
T temp = _tail._value;
_tail = _tail._previous;
_tail._next = null;
_size--;
return temp;
}
public T remove(T element){
if(_size == 0){
return null;
}
DoubleNode current = _head;
DoubleNode previous = null;
T temp = null;
do{
if(current._value == element){
temp = current._value;
if(previous == null){
_head = _head._next;
_head._previous = null;
}
else{
previous._next = current._next;
}
}
previous = current;
current = current._next;
}while(current != null);
return temp;
}
public T first(){
return _head._value;
}
public T last(){
return _tail._value;
}
public boolean contains(T target){
if(_size == 0){
return false;
}
DoubleNode temp = _head;
do{
if(temp._value == target){
return true;
}
temp = temp._next;
}while(temp != null);
return false;
}
public boolean isEmpty(){
if(_size == 0){
return true;
}
return false;
}
public int size(){
return _size;
}
public void add(T element)
{
int add = 0;
DoubleNode temp = new DoubleNode();
temp._value = element;
DoubleNode point = _head;
DoubleNode placeHolder;
if(_head == null) {
_head = temp;
_tail = temp;
_size++;
return;
}
else if((Integer)element <= (Integer)_head._value){
temp._next = _head;
_head._previous = temp;
_head = temp;
_size++;
return;
}
do {
if(point._next == null){
point._next = temp;
temp._previous = point;
_tail = temp;
_size++;
return;
}
else if((Integer)point._next._value >= (Integer)element && (Integer)point._value < (Integer)element){
placeHolder = point._next;
point._next = temp;
placeHolder._previous = temp;
temp._next = placeHolder;
temp._previous = point;
_size++;
return;
}
point = point._next;
} while (point != null);
_size++;
}
public String toString(){
String returnString = "";
if(_size == 0){
return returnString;
}
DoubleNode temp = _head;
do{
returnString += temp._value + " ";
temp = temp._next;
}while(temp != null);
return returnString;
}
private class DoubleNode {
private DoubleNode _previous;
private DoubleNode _next;
private T _value;
public DoubleNode() {
_previous = null;
_next = null;
_value = null;
}
public DoubleNode(T value){
_previous = null;
_next = null;
_value = value;
}
}
}
/**
* DoubleOrderedList testing area.
*
* #author (your name), Acuna
* #version (version)
*/
class Driver {
public static void main(String [] args) {
DoubleList<Integer> list = new DoubleList<>();
//RA: These are _extremely_ simple tests - do not use them when doing
// your writeup.
list.add(23);
list.add(24);
list.add(16);
list.add(3);
list.add(7);
list.add(17);
list.add(9);
list.add(13);
list.add(14);
list.add(1);
System.out.println("\nsize = " + list.size());
System.out.println(list);
list.remove(7);
System.out.println(list);
list.removeFirst();
System.out.println(list);
list.remove(17);
System.out.println(list);
list.removeLast();
System.out.println(list);
list.remove(14);
System.out.println(list);
list.removeLast();
System.out.println(list);
I don't think your bug is in removeLast. It's in the remove function, and it corrupts your list, causing further manipulations of the list to behave incorrectly.
When you remove an item from the middle of a double linked list, you need to stitch up the item before the removed item, and the item after the removed item. You are doing the first operation, but not the second. For example, suppose I have three elements in the list: L X R. I want to remove X. I have to set L._next = R (you do that), and also set R._previous = L (you don't do that). At that point, your list becomes corrupt, because your reverse links are off.
Take a look at your loop at remove function.
do{
if(current._value == element){
temp = current._value;
if(previous == null){
_head = _head._next;
_head._previous = null;
}
else{
previous._next = current._next;
//next line is missing
previous._next._previous = previous;
}
}
previous = current;
current = current._next;
}while(current != null);
Also, it's not efficient to loop while(current != null), consider (while !found && current != null) or break statement.

Why does this sort algorithm only sort to the value of the final integer?

Whenever I try to sort this linked list, it only sorts it up to the final number in the list. So for example, with a linked list of [5, 8, 4, 9, 0, 1, 2, 3, 7, 6] the only return is [0, 1, 2, 3, 4, 5, 6]. I feel like there is a silly error somewhere in here that, despite the last hour trying to find it, I haven't been able to identify.
Here's my code:
class SortyList
{
{
private int key;
private Node next;
private Node(int key, Node next)
{
this.key = key;
this.next = next;
}
}
private Node head;
private Node first;
public SortyList()
{
head = new Node(0, null);
}
public SortyList(int first, int ... rest)
{
Node last = new Node(first, null);
this.first = last;
for (int index = 0; index < rest.length; index += 1)
{
last.next = new Node(rest[index], null);
last = last.next;
}
head = new Node(0, null);
}
public SortyList sort()
{
first = sort(first);
return this;
}
private Node sort(Node unsorted)
{
if (unsorted == null || unsorted.next == null || unsorted.next.next == null) {
return unsorted;
}
Node left = unsorted;
Node lo = left;
unsorted = unsorted.next;
Node right = unsorted;
Node ro = right;
unsorted = unsorted.next;
for (int i = 0; unsorted != null; i++) {
if (i % 2 == 0) {
Node temp = left;
left = unsorted;
temp.next = left;
} else {
Node temp = right;
right = unsorted;
temp.next = right;
}
unsorted = unsorted.next;
}
Node r = lo;
left = sort(lo);
right = sort(ro);
Node merged;
Node end;
if (left.key > right.key) {
merged = right;
right = right.next;
} else {
merged = left;
left = left.next;
}
end = merged;
while (left != null && right != null) {
if (left.key > right.key) {
end.next = right;
right = right.next;
} else {
end.next = left;
left = left.next;
}
end = end.next;
}
if (left != null) {
end = left;
} else if (right != null) {
end = right;
}
return merged;
}
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append('[');
if (first != null)
{
Node temp = first;
builder.append(temp.key);
temp = temp.next;
while (temp != null)
{
builder.append(", ");
builder.append(temp.key);
temp = temp.next;
}
}
builder.append(']');
return builder.toString();
}
public static void main(String[] args)
{
System.out.println(new SortyList(5, 8, 4, 9, 0, 1, 2, 3, 7, 6).sort());
}
}

singly linked-list in java implementation

I have being given a task to implement the following method in Java: SubList(S, L) returns true if list S is a sublist of list L.
I need to use the following notation when I process lists as an abstract object in the recurrence relations. Given a list L, we write L = [H|R] where H is the head of the list and R is the rest of the list. For an empty list L, we write L = []. For example, if L = [1, 2, 3, 4, 5], H = 1, and R = [2, 3, 4, 5].
Hence my tasks are:
a) Provide the recurrence relations for SubList(S, L) using the above list notation.
b) Implement the recursive algorithm in Java using the recurrence relations.
Being stuck on this task for a day and a half now and still having trouble how to do this. Appreciate, if anyone can help me to solve this problem.
This is the java code I have been given to work with.
class SLLNode {
public Object info; // This is the data
public SLLNode next; // this is the address of the next node
public SLLNode() { // Here's how we construct an empty list.
next = null;
}
public SLLNode(Object el) {
info = el; next = null;
}
public SLLNode(Object el, SLLNode ptr) {
info = el; next = ptr;
}
}
class SLList {
protected SLLNode head = null;
public SLList() {
}
public void setToNull() {
head = null;
}
public boolean isEmpty() {
return head == null;
}
public Object first() {
return head.info;
}
public SLLNode head() {
return head;
}
public void printAll() {
for (SLLNode tmp = head; tmp != null; tmp = tmp.next)
System.out.print(tmp.info.toString());
}
public void add(Object el) {
head= new SLLNode(el,head);
}
public Object find(Object el) {
SLLNode tmp = head;
for ( ; tmp != null && !el.equals(tmp.info); tmp = tmp.next);
if (tmp == null)
return null;
else return tmp.info;
}
public boolean member(Object el) {
SLLNode tmp = head;
for ( ; tmp != null && !el.equals(tmp.info); tmp = tmp.next);
if (tmp == null)
return false;
else return true;
}
public Object deleteHead() { // remove the head and return its info;
Object el = head.info;
head = head.next;
return el;
}
public void delete(Object el) { // find and remove el;
if (head != null) // if non-empty list;
if (el.equals(head.info)) // if head needs to be removed;
head = head.next;
else {
SLLNode pred = head, tmp = head.next;
for ( ; tmp != null && !(tmp.info.equals(el));
pred = pred.next, tmp = tmp.next);
if (tmp != null) // if found
pred.next = tmp.next;
}
}
}
SubList([], L) = true (1)
SubList(H|[], H|*) = true (2)
SubList(H|[], []) = false (3)
SubList(SH|[], H|R) = SubList(SH|[], H|[]) OR SubList(SH|[], R) (4)
SubList(SH|SR, L) = SubList(SH|[], L) AND SubList(SR, L) (5)
In english, it means that if L contains the first element of your sublist S AND that it contains the remaining elements of the sublist, then your SubList method is gonna return true.
The recursion here visible on the 4th and 5th lines, where you see that we are invoking the same function again and again until SR contains only one element.
Ex:
L = [1,2,5]
S = [1,5]
SubList(S, L) = SubList([1,5], [1,2,5])
= SubList(1|[5], 1|[2,5]) (4+5)
= SubList(1|[], 1|[2,5]) AND SubList([5], 1|[2,5])
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR SubList(5|[], [2,5]))
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR (SubList(5|[], 2|[]) OR SubList(5|[], [5])))
= SubList(1|[], 1|[2,5]) AND (SubList(5|[], 1|[]) OR (SubList(5|[], 2|[]) OR SubList(5|[], 5|[])))
= true AND (false OR (false OR true))
= true AND true
= true
Possible Java implementation:
public SLList(SLNode h) {
this.head = h;
}
public SLList singletonList(SLNode n) {
return new SLList(new SLNode(n.info));
}
public SLList remainingList(SLNode n) {
if(n == null) return new SLList();
return new SLList(n);
}
private static boolean subList(SLList s, SLList l) {
if(s.isEmpty()) return true;
if(l.isEmpty()) return false;
if(s.head.next == null && l.first().equals(s.first())) return true;
return (subList(singletonList(s.head), singletonList(l.head)) ||
subList(singletonList(s.head), remainingList(l.head.next))) &&
subList(remainingList(s.head.next), l);
}
I haven't tested the code, there might be some null checks missing but the important thing is that you get the idea of how recursion works.

How to reverse a singly-linked list in blocks of some given size in O(n) time in place?

I recently encounter an algorithm problem:
Reverse a singly-linked list in blocks of k in place. An iterative approach is preferred.
The first block of the resulting list should be maximal with regards to k. If the list contains n elements, the last block will either be full or contain n mod k elements.
For example:
k = 2, list = [1,2,3,4,5,6,7,8,9], the reversed list is [8,9,6,7,4,5,2,3,1]
k = 3, list = [1,2,3,4,5,6,7,8,9], the reversed list is [7,8,9,4,5,6,1,2,3]
My code is shown as below.
Is there an O(n) algorithm that doesn't use a stack or extra space?
public static ListNode reverse(ListNode list, int k) {
Stack<ListNode> stack = new Stack<ListNode>();
int listLen = getLen(list);
int firstBlockSize = listLen % k;
ListNode start = list;
if (firstBlockSize != 0) {
start = getBlock(stack, start, firstBlockSize);
}
int numBlock = (listLen) / k;
for (int i = 0; i < numBlock; i++) {
start = getBlock(stack, start, k);
}
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while (!stack.empty()) {
cur.next = stack.peek();
cur = stack.pop();
while (cur.next != null) {
cur = cur.next;
}
}
return dummy.next;
}
public static ListNode getBlock(Stack<ListNode> stack, ListNode start, int blockSize) {
ListNode end = start;
while (blockSize > 1) {
end = end.next;
blockSize--;
}
ListNode temp = end.next;
end.next = null;
stack.push(start);
return temp;
}
public static int getLen(ListNode list) {
ListNode iter = list;
int len = 0;
while (iter != null) {
len++;
iter = iter.next;
}
return len;
}
This can be done in O(n) time using O(1) space as follows:
Reverse the entire list.
Reverse the individual blocks.
Both can be done using something very similar to the standard way to reverse a singly linked-list and the overall process resembles reversing the ordering of words in a string.
Reversing only a given block is fairly easily done by using a length variable.
The complication comes in when we need to move from one block to the next. The way I achieved this was by having the reverse function return both the first and last nodes and having the last node point to the next node in our original linked-list. This is necessary because the last node's next pointer needs to be updated to point to the first node our next reverse call returns (we don't know what it will need to point to before that call completes).
For simplicity's sake, I used a null start node in the code below (otherwise I would've needed to cater for the start node specifically, which would've complicated the code).
class Test
{
static class Node<T>
{
Node next;
T data;
Node(T data) { this.data = data; }
#Override
public String toString() { return data.toString(); }
}
// reverses a linked-list starting at 'start', ending at min(end, len-th element)
// returns {first element, last element} with (last element).next = (len+1)-th element
static <T> Node<T>[] reverse(Node<T> start, int len)
{
Node<T> current = start;
Node<T> prev = null;
while (current != null && len > 0)
{
Node<T> temp = current.next;
current.next = prev;
prev = current;
current = temp;
len--;
}
start.next = current;
return new Node[]{prev, start};
}
static <T> void reverseByBlock(Node<T> start, int k)
{
// reverse the complete list
start.next = reverse(start.next, Integer.MAX_VALUE)[0];
// reverse the individual blocks
Node<T>[] output;
Node<T> current = start;
while (current.next != null)
{
output = reverse(current.next, k);
current.next = output[0];
current = output[1];
}
}
public static void main(String[] args)
{
//Scanner scanner = new Scanner(System.in);
Scanner scanner = new Scanner("3 9 1 2 3 4 5 6 7 8 9\n" +
"2 9 1 2 3 4 5 6 7 8 9");
while (scanner.hasNextInt())
{
int k = scanner.nextInt();
// read the linked-list from console
Node<Integer> start = new Node<>(null);
Node<Integer> current = start;
int n = scanner.nextInt();
System.out.print("Input: ");
for (int i = 1; i <= n; i++)
{
current.next = new Node<>(scanner.nextInt());
current = current.next;
System.out.print(current.data + " ");
}
System.out.println("| k = " + k);
// reverse the list
reverseByBlock(start, k);
// display the list
System.out.print("Result: ");
for (Node<Integer> node = start.next; node != null; node = node.next)
System.out.print(node + " ");
System.out.println();
System.out.println();
}
}
}
This outputs:
Input: 1 2 3 4 5 6 7 8 9 | k = 3
Result: 7 8 9 4 5 6 1 2 3
Input: 1 2 3 4 5 6 7 8 9 | k = 2
Result: 8 9 6 7 4 5 2 3 1
Live demo.
Here is an iterative way of doing it... you read my full explanation here
Node reverseListBlocks1(Node head, int k) {
if (head == null || k <= 1) {
return head;
}
Node newHead = head;
boolean foundNewHead = false;
// moves k nodes through list each loop iteration
Node mover = head;
// used for reversion list block
Node prev = null;
Node curr = head;
Node next = null;
Finish: while (curr != null) {
// move the mover just after the block we are reversing
for (int i = 0; i < k; i++) {
// if there are no more reversals, finish
if (mover == null) {
break Finish;
}
mover = mover.next;
}
// reverse the block and connect its tail to the rest of
// the list (at mover's position)
prev = mover;
while (curr != mover) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
// establish the new head, if we didn't yet
if (!foundNewHead) {
newHead = prev;
foundNewHead = true;
}
// connects previous block's head to the rest of the list
// move the head to the tail of the reversed block
else {
head.next = prev;
for (int i = 0; i < k; i++) {
head = head.next;
}
}
}
return newHead;
}
The easiest way to reverse the single linked list is as follows.
private void reverse(Node node)
{
Node current = Node;
Node prev = null;
Node next = null;
if(node == null || node.next == null)
{
return node;
}
while(current != null)
{
next = current.next;
//swap
current.next = prev;
prev = current;
current = next;
}
node.next = current;
}
This section contains multiple Single Linked List Operation
import java.util.Scanner;
import java.util.Stack;
public class AddDigitPlusLL {
Node head = null;
int len =0;
static class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
public void insertFirst(int data) {
Node newNode = new Node(data);
if (head != null)
newNode.next = head;
head = newNode;
}
public void insertLast(int data) {
Node temp = head;
Node newNode = new Node(data);
if (temp == null)
head = newNode;
else {
Node previousNode = null;
while (temp != null) {
previousNode = temp;
temp = temp.next;
}
previousNode.next = newNode;
}
}
public Long getAllElementValue() {
Long val = 0l;
Node temp=head;
while(temp !=null) {
if(val == 0)
val=(long) temp.data;
else
val=val*10+temp.data;
temp = temp.next;
}
System.out.println("value is :" + val);
return val;
}
public void print(String printType) {
System.out.println("----------- :"+ printType +"----------- ");
Node temp = head;
while (temp != null) {
System.out.println(temp.data + " --> ");
temp = temp.next;
}
}
public void generateList(Long val) {
head = null;
while(val > 0) {
int remaining = (int) (val % 10);
val = val/10;
insertFirst(remaining);
}
}
public void reverseList(Long val) {
head =null;
while(val >0) {
int remaining = (int) (val % 10);
val = val/10;
insertLast(remaining);
}
}
public void lengthRecursive(Node temp) {
if(temp != null) {
len++;
lengthRecursive(temp.next);
}
}
public void reverseUsingStack(Node temp) {
Stack<Integer> stack = new Stack<Integer>();
while(temp != null) {
stack.push(temp.data);
temp = temp.next;
}
head = null;
while(!stack.isEmpty()) {
int val = stack.peek();
insertLast(val);
stack.pop();
}
print(" Reverse Using Stack");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner s = new Scanner(System.in);
AddDigitPlusLL sll = new AddDigitPlusLL();
sll.insertFirst(5);
sll.insertFirst(9);
sll.insertLast(8);
sll.print("List Iterate");
Long val = sll.getAllElementValue();
System.out.println("Enter the digit to add");
Long finalVal = val +s.nextInt();
s.close();
sll.generateList(finalVal);
sll.print("Add int with List Value");
sll.reverseList(finalVal);
sll.print("Reverse the List");
sll.lengthRecursive(sll.head);
System.out.println("Length with Recursive :"+ sll.len);
sll.print("Before call stack reverse method");
sll.reverseUsingStack(sll.head);
}
}

Categories

Resources