I want to maintain order of the elements being added in a list. So, I used a LinkedList in Java.
Now I want to be able to swap two elements in the linked list. First of all, I cannot find an elementAt() for LinkedList. Also, there is no way to add element at a specified position.
There is a Collections.swap(List<?> list, int i, int j) that you can use to swap two elements of a List<?>. There's also LinkedList.get(int index) and LinkedList.add(int index, E element) (both are methods specified by interface List). All of these operations will be O(N) since a LinkedList does not implements RandomAccess.
Check out the Javadocs for LinkedList
To find an element at an index use get(int index)
To place an element at a certain index use set(int index, Object element)
If you are writing your own LinkedList class for exercise (i.e. for a project or school), try making two temporary Object variables and two ints to hold their position in the List. Then, use add(int, Object) to add the first in the 2nd position, second in the 1st position.
public class SwapNode {
public static Node head;
public static void main(String[] args) {
SwapNode obj = new SwapNode();
obj.insertAtEnd(5);
obj.insertAtEnd(6);
obj.insertAtEnd(4);
obj.insertAtEnd(7);
obj.insertAtEnd(3);
obj.insertAtEnd(8);
obj.insertAtEnd(2);
obj.insertAtEnd(9);
obj.insertAtEnd(1);
obj.print(head);
System.out.println("*** Swapped ***");
obj.swapElementValue(4, 2);
}
public void swapElementValue(int value1, int value2) {
if (value1 == value2) {
System.out.println("Values same, so no need to swap");
return;
}
boolean found1 = false, found2 = false;
Node node = head;
while (node != null && !(found1 && found2)) {
if (node.data == value1) {
node.data = value2;
found1 = true;
node = node.next;
continue;
}
if (node.data == value2) {
node.data = value1;
found2 = true;
node = node.next;
continue;
}
node = node.next;
}
if (found1 && found2) {
print(head);
} else {
System.out.println("Values not found");
}
}
public void insertAtEnd(int data) {
Node newNode = new Node(data);
if (head == null) {
head = newNode;
return;
}
Node temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = newNode;
}
public void print(Node head) {
Node temp = head;
while(temp != null) {
System.out.print(temp.data);
temp = temp.next;
}
System.out.println();
}
static class Node {
private int data;
public Node next;
public Node(int data) {
this.data = data;
}
}
}
add
Does this what you want?
If you want to keep the list in a sorted state, why not just insert the element with addfirst
and then sort the list using Collections.sort
Take a look at ArrayList , this class will both maintain the insertion order and provide O(1) random access.
// I tried to reduce time complexity here, in 3 while loops (get() and set() use 4 while loop)
void swapAt(int index1, int index2){ // swapping at index
Node tmp = head;
int count=0;
int min, max; // for future reference to reduce time complexity
if(index1<index2){
min = index1;
max = index2;
}
else{
min = index2;
max = index1;
}
int diff = max - min;
while(min!=count){
tmp= tmp.next;
count++;
}
int minValue = tmp.data;
while(max!=count){
tmp= tmp.next;
count++;
}
int maxValue = tmp.data;
tmp.data = minValue;
tmp = head;
count =0;
while(min!=count){
tmp= tmp.next;
count++;
}
tmp.data = maxValue;
}
Related
import java.io.*;
import java.util.Arrays;
public class tester {
static public class LinkedList {
Node head; // head of list
Node sorted;
int size;
// Linked list Node.
// This inner class is made static
// so that main() can access it
public class Node {
Object data;
Node next;
Node() {
}
// constructor
Node(Object data) {
this.data = data;
next = null;
}
// constructor
Node(Object data, Node n) {
this.data = data;
next = n;
}
}
public void addFirst(Object d) {
head = new Node(d);
size++;
}
public void addLast(Object d) {
Node temp = head;
while (temp != null) {
temp = temp.next;
}
temp = new Node(d,null);
size++;
}
int getSize() {
return size;
}
boolean isSorted()
{
if (head == null)
return true;
// Traverse the list till last node and return
// false if a node is smaller than or equal
// its next.
for (Node t = head; t.next != null; t=t.next)
if ((int)t.data <= (int)t.next.data)
return false;
return true;
}
void InsertionSort()
{
// Initialize sorted linked list
sorted = null;
Node current = head;
// Traverse the given linked list and insert every
// node to sorted
while (current != null)
{
// Store next for next iteration
Node next = current.next;
// insert current in sorted linked list
sortedInsert(current);
// Update current
current = next;
}
// Update head_ref to point to sorted linked list
head = sorted;
}
void sortedInsert(Node newnode)
{
/* Special case for the head end */
if (sorted == null || (int)sorted.data >= (int)newnode.data)
{
newnode.next = sorted;
sorted = newnode;
}
else
{
Node current = sorted;
/* Locate the node before the point of insertion */
while (current.next != null && (int)current.next.data < (int)newnode.data)
{
current = current.next;
}
newnode.next = current.next;
current.next = newnode;
}
}
public void MergeSort() {
Queue q = new Queue();
int count = 0;
int[] sublist1 = null;
int[] sublist2 = null;
int[] tempList = null;
// Node cur = head;
for (Node cur = head; cur != null; cur = cur.next) {
LinkedList newList = new LinkedList();
newList.addFirst(cur.data);
q.enqueue(newList);
}
while (q.size > 1) {
sublist1[count] = (int) q.dequeue();
if (q.size >= 1) {
sublist2[count] = (int) q.dequeue();
}
Arrays.sort(sublist1);
Arrays.sort(sublist2);
tempList = merge(sublist1, sublist2);
}
q.enqueue(tempList);
}
public int[] merge(int[] a, int[] b) {
int[] answer = new int[a.length + b.length];
int i = 0, j = 0, k = 0;
while (i < a.length && j < b.length)
answer[k++] = a[i] < b[j] ? a[i++] : b[j++];
while (i < a.length)
answer[k++] = a[i++];
while (j < b.length)
answer[k++] = b[j++];
return answer;
}
}
static class Queue {
int front, rear, size;
int capacity;
Object array[];
// constructor
public Queue() {
front = 0;
rear = 0;
size = 0;
}
// constructor
public Queue(int capacity) {
this.capacity = capacity;
front = this.size = 0;
rear = capacity - 1;
array = new Object[this.capacity];
}
boolean isFull(Queue queue) {
return (queue.size == queue.capacity);
}
boolean isEmpty(Queue queue) {
return (queue.size == 0);
}
void enqueue(Object newList) {
if (isFull(this))
return;
this.rear = (this.rear + 1) % this.capacity;
this.array[this.rear] = newList;
this.size = this.size + 1;
}
Object dequeue() {
if (isEmpty(this))
return Integer.MIN_VALUE;
Object item = (int) this.array[this.front];
this.front = (this.front + 1) % this.capacity;
this.size = this.size - 1;
return item;
}
}
public static void main(String[] args) {
LinkedList A = new LinkedList();
LinkedList A2 = new LinkedList();
int ramdomListSize = 20000;
for(int i = 0; i < ramdomListSize; i++) {
int randomInt = (int)(Math.random() * 3000000);
A.addLast(randomInt);
A2.addLast(randomInt);
}
//measure the time cost of merge sort
double then = System.currentTimeMillis();
A.MergeSort();
double now = System.currentTimeMillis();
System.out.println("Time cost in milliseconds for mergesort " + (now - then));
System.out.println(A.isSorted()); //verify that your merge sort implementation works.
System.out.println("Size of list A is: " + A.getSize());
//measure the time cost of insertion sort
then = System.currentTimeMillis();
A2.InsertionSort();
now = System.currentTimeMillis();
System.out.println("Time cost in milliseconds for insertionsort " + (now - then));
System.out.println(A2.isSorted() ); //verify that your insertion sort works.
System.out.println("Size of list A2 is: " + A2.getSize());
}//end of main
}
Expected output:
Time cost in milliseconds for mergesort: 37.0
true
Size of list A is: 20000
Time cost in milliseconds for insertionsort: 660.0
true
Size of list A2 is: 20000
My Output:
Time cost in milliseconds for mergesort: 1.0
true
Size of list A is: 20000
Time cost in milliseconds for insertionsort: 0.0
true
Size of list A2 is: 20000
Your InsertionSort() doesn't do anything.
Node current = head;
while (current != null) {
....
}
You never assign head field, so it is always null and the loop is never executed.
The only assignment to head is done in addFirst() method which is never called.
You should declare a field Node current to keep track of the last Node object.
Your method addLast(Object d) does not add the object to the list. Storing a different object in a variable does not affect the previously stored object so temp = new Node(d,null); will only change value of the variable temp.
The method should be like this
public void addLast(Object d) {
if (current != null) {
current.next = new Node(d,null);
current = current.next;
}
else {
head = new Node(d, null);
current = head;
}
size++;
}
Your implementation of merge sort is also incorrect. addFirst should store previous head before updating and make the next field of the new head point to the old one. sublist1 and sublist2 are always null and count always remains 0. If you want to sort using merge sort, Arrays.sort should not be used because it uses quick sort for primitive types like int. Check out the correct implementation of merge sort here.
I am having a bit of trouble understanding how to place an object in a linked.
In this case, if there is already an object at the specific index, it won't replace it (that is for another method). I guess I am having trouble understanding how to get to a specific index, retrieve the data from that index, and then either put data there and connect the nodes or tell the user there is already an object there.
Here is my code:
public class CourseList {
private Coursenode head;
int currentSize;
public void insertAtIndex(Course c, int index) {
Coursenode insert =new Coursenode(c,head);
Coursenode temp = new Coursenode();
if (index > currentSize - 1 || index < 0) {
throw (new IndexOutOfBoundsException());
}
for(int x = 0; x < index; x++) {
if (insert.getNext()!= null) {
temp = insert;
insert.setNext(insert);
insert.setData(temp.getData());
}
if (insert.getNext() == null && x == index) {
insert.setNext(insert.getNext());
}
if (insert.getNext() != null && x == index) {
System.out.println("There is already a Course at that Index");
}
}
}
}
Here is the inner class Coursenode:
public class Coursenode {
private Course data;
private Coursenode next;
public Coursenode() {
this.data = null;
this.next = null;
}
public Coursenode(Course course, Coursenode next) {
this.data=course;
this.next= next;
}
public Coursenode(Coursenode x) {
this.data = x.getData();
this.next = x.getNext();
}
public Course getData() {
return data;
}
public void setData(Course data) {
this.data = data;
}
public Coursenode getNext() {
return next;
}
public void setNext(Coursenode next) {
this.next = next;
}
//Clone method
public void clone(Coursenode new_cn){
new_cn = new Coursenode (this.getData(),this.getNext());
}
}
Any thought would be appreciated, I suspect I am getting lost within the head reference between nodes but I can't quite figure out how to solve the problem.
There are three ways (assuming positive index values) to make an insertion at an index in a linked list:
At the head (index == 0)
After the tail (index >= currentSize)
In the middle (at an occupied index) (index > 0 && index < currentSize)
There may be a tendency to think that inserting at the tail is another case, but later we'll see that insertion at the tail is the same as an insertion in the middle, because the tail will be slid forward.
If the insertion is at the head, you need to set the next of the inserted node to the old head and then set head to the inserted node:
private void insertAtHead(Course course) {
Coursenode insertedNode = new Coursenode(c, head);
head = insertedNode;
}
If the insertion occurs past the tail, a common way of dealing with this is to throw some sort of exception, such as an IndexOutOfBoundsException:
throw new IndexOutOfBoundsException("Cannot insert course after the tail of the course list");
If the insertion occurs at an occupied index, the existing node (and all nodes after the existing node) must be pushed forward. This means that the next of the inserted node must be set to the node that currently occupies the index and the next of the node previous to the node at the current index must be set to the inserted node. In essence, the inserted node is fused into the list. To do this, the list must be traversed until the occupied node is found:
private void insertAtOccupied(Course course, int index) {
Coursenode previous = null;
Coursenode current = head;
for (int i = 1; i <= index; i++) {
// Track the previous and current nodes
// previous = node at i - 1
// current = node at i
previous = current;
current = current.next;
}
Coursenode insertedNode = new Coursenode(c, current.next);
previous.next = insertedNode;
}
Pulling these cases together, we can create the following logic:
public void insertAt(Course course, int index) {
if (index == 0) {
insertAtHead(course);
}
else if (index >= currentSize) {
throw new IndexOutOfBoundsException("Cannot insert course after the tail of the course list");
}
else if (index > 0 && index < currentSize) {
insertAtOccupied(course, index);
}
}
First of all in a linkedlist if
index < linkedlistsize
then there is an object already in a linkedlist. If you have a null node in node.next that how you know you have reached the end of your linked list.
public class CourseList {
private Coursenode head;
int currentSize;
public void insertAtIndex(Course c, int index) {
Coursenode insert =new Coursenode(c,head);
Coursenode temp = new Coursenode();
if (index > currentSize - 1 || index < 0) {
throw (new IndexOutOfBoundsException());
}
//tempnode = head;
for(int x=1; x< index;x++) {
//tempnode = tempnode.next;
}
//nodeatindex = tempnode;
//you can get details of the node
}
Hope this helps!
I have to sort through a LinkedList, but i can't figure out why it only sorts it once and then stops. I am having a hard time understanding generic types and how to use them. Most of the examples i found were about sorting integer arrays, but i still couldn't translate those examples into my sort method. Anything that could help me understand how to sort this would be greatly appreciated.
public void sort() {
Node<T> current = head;
while(current != null){
if(current.getNext()!=null && current.getItem().compareTo(current.getNext().getItem()) < 0){
T temp = current.getItem();
current.setItem(current.getNext().getItem());
current.getNext().setItem(temp);
}
current = current.getNext();
}
current = head;
}
Here is my LinkedList class
public class LinkedList<T extends Comparable<T>> implements LinkedList161<T> {
protected Node<T> head;
protected int size;
public LinkedList() {
head = null;
size = 0;
}
public void add(T item, int index) {
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("out of bounds");
}
if(index == 0){
head = new Node<T>(item, head);
}
else{
Node<T> current = head;
for(int i = 0; i < index -1; i ++){
current = current.getNext();
}
current.setNext(new Node<T>(item, current.getNext()));
}
size++;
}
public void addFirst(T item) {
head = new Node<T>(item, head);
size++;
}
public void addToFront(T item) {
head = new Node<T>(item, head);
size++;
}
public void addToBack(T item) {
if(head == null){
head = new Node<T>(item);
size++;
}
else{
Node<T> temp = head;
while(temp.getNext() != null){
temp = temp.getNext();
}
temp.setNext(new Node<T>(item));
size++;
}
}
public void remove(int index) {
if(index < 0 || index > size){
System.out.println("Index out of bounds");
}
if(index == 0){
head = head.getNext();
}else{
Node<T> current = head;
for(int i = 0; i < index;i++){
current = current.getNext();
}
current.setNext(current.getNext().getNext());
}
size--;
}
public T get(int index){
Node<T> p = head;
for(int i = 0; i < index;i++){
p = p.getNext();
}
return p.getItem();
}
public void clear() {
head = null;
size = 0;
}
public int size() {
return size;
}
#Override
public String toString() {
String result = "";
if (head == null)
return result;
for (Node<T> p = head; p != null; p = p.getNext()) {
result += p.getItem() + "\n";
}
return result.substring(0,result.length()-1); // remove last \n
}
#Override
public void sort() {
Node<T> current = head;
for(int i = 0; i < size;i++){
if(current.getNext()!=null && current.getItem().compareTo(current.getNext().getItem()) < 0){
T temp = current.getItem();
current.setItem(current.getNext().getItem());
current.getNext().setItem(temp);
}
current = current.getNext();
}
current = head;
}
}
Here is my Node class
public class Node<T> implements Node161<T>{
protected T item;
protected Node<T> next;
public Node(T item, Node<T> next) {
setItem(item);
setNext(next);
}
public Node(T item) {
setItem(item);
}
public T getItem() {
return item;
}
public void setItem(T i) {
item = i;
}
public void setNext(Node<T> n) {
next = n;
}
public Node<T> getNext() {
return next;
}
#Override
public String toString() {
return item.toString();
}
}
Your implementation of sort does just one step of sorting: it orders adjacent items and after this step things get better but the whole collection will not be sorted. You should repeat this step until your collection gets sorted.
Note that this algorithm is not efficient. You should look at some more sophisticated approach like merge sort
Wiki merge sort article now includes a simple but fast bottom up merge sort for linked lists that uses a small array (usually 26 to 32) of pointers to the first nodes of a list, where array[i] is either null or points to a list of size 2 to the power i. Unlike some other approaches, there's no scanning of lists, instead, the array is used along with a common merge function that merges two already sorted lists. Link to article:
http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists
I was trying to reverse a linked list using recursion. I got the solution, but can't get it to work for below question found on internet.
Reverse a linked list using recursion but function should have void
return type.
I was able to implement the function with return type as Node. Below is my solution.
public static Node recursive(Node start) {
// exit condition
if(start == null || start.next == null)
return start;
Node remainingNode = recursive(start.next);
Node current = remainingNode;
while(current.next != null)
current = current.next;
current.next = start;
start.next = null;
return remainingNode;
}
I cannot imagine if there will be such a solution to this problem.
Any suggestions ?
Tested, it works (assuming you have your own implementation of a linked list with Nodes that know the next node).
public static void reverse(Node previous, Node current) {
//if there is next node...
if (current.next != null) {
//...go forth and pwn
reverse(current, current.next);
}
if (previous == null) {
// this was the start node
current.next= null;
} else {
//reverse
current.next= previous;
}
}
You call it with
reverse(null, startNode);
public void recursiveDisplay(Link current){
if(current== null)
return ;
recursiveDisplay(current.next);
current.display();
}
static StringBuilder reverseStr = new StringBuilder();
public static void main(String args[]) {
String str = "9876543210";
reverse(str, str.length() - 1);
}
public static void reverse(String str, int index) {
if (index < 0) {
System.out.println(reverseStr.toString());
} else {
reverseStr.append(str.charAt(index));
reverse(str, index - 1);
index--;
}
}
This should work
static void reverse(List list, int p) {
if (p == list.size() / 2) {
return;
}
Object o1 = list.get(p);
Object o2 = list.get(list.size() - p - 1);
list.set(p, o2);
list.set(list.size() - p - 1, o1);
reverse(list, p + 1);
}
though to be efficient with LinkedList it should be refactored to use ListIterator
I am not familiar with Java, but here is a C++ version. After reversing the list, the head of list is still preserved, which means that the list can still be accessible from the old list head List* h.
void reverse(List* h) {
if (!h || !h->next) {
return;
}
if (!h->next->next) {
swap(h->value, h->next->value);
return;
}
auto next_of_next = h->next->next;
auto new_head = h->next;
reverse(h->next);
swap(h->value, new_head->value);
next_of_next->next = new_head;
h->next = new_head->next;
new_head->next = nullptr;
}
Try this code instead - it actually works
public static ListElement reverseListConstantStorage(ListElement head) {
return reverse(null,head);
}
private static ListElement reverse(ListElement previous, ListElement current) {
ListElement newHead = null;
if (current.getNext() != null) {
newHead = reverse(current, current.getNext());
} else {//end of the list
newHead=current;
newHead.setNext(previous);
}
current.setNext(previous);
return newHead;
}
public static Node recurse2(Node node){
Node head =null;
if(node.next == null) return node;
Node previous=node, current = node.next;
head = recurse2(node.next);
current.next = previous;
previous.next = null;
return head;
}
While calling the function assign the return value as below:
list.head=recurse2(list.head);
The function below is based on the chosen answer from darijan, all I did is adding 2 lines of code so that it'd fit in the code you guys want to work:
public void reverse(Node previous, Node current) {
//if there is next node...
if (current.next != null) {
//...go forth and pwn
reverse(current, current.next);
}
else this.head = current;/*end of the list <-- This line alone would be the fix
since you will now have the former tail of the Linked List set as the new head*/
if (previous == null) {
// this was the start node
current.next= null;
this.tail = current; /*No need for that one if you're not using a Node in
your class to represent the last Node in the given list*/
} else {
//reverse
current.next= previous;
}
}
Also, I've changed it to a non static function so then the way to use it would be: myLinkedList.reverse(null, myLinkedList.head);
Here is my version - void ReverseWithRecursion(Node currentNode)
- It is method of LinkListDemo Class so head is accessible
Base Case - If Node is null, then do nothing and return.
If Node->Next is null, "Make it head" and return.
Other Case - Reverse the Next of currentNode.
public void ReverseWithRecursion(Node currentNode){
if(currentNode == null) return;
if(currentNode.next == null) {head = currentNode; return;}
Node first = currentNode;
Node rest = currentNode.next;
RevereseWithRecursion(rest);
first.next.next = first;
first.next = null;
}
You Call it like this -
LinkListDemo ll = new LinkListDemo(); // assueme class is available
ll.insert(1); // Assume method is available
ll.insert(2);
ll.insert(3);
ll.ReverseWithRecursion(ll.head);
Given that you have a Node class as below:
public class Node
{
public int data;
public Node next;
public Node(int d) //constructor.
{
data = d;
next = null;
}
}
And a linkedList class where you have declared a head node, so that it can be accessed by the methods that you create inside LinkedList class. The method 'ReverseLinkedList' takes a Node as an argument and reverses the ll.
You may do a dry run of the code by considering 1->2 as the linkedList. Where node = 1, node.next = 2.
public class LinkedList
{
public Node? head; //head of list
public LinkedList()
{
head = null;
}
public void ReverseLinkedList(Node node)
{
if(node==null)
{
return;
}
if(node.next==null)
{
head = node;
return;
}
ReverseLinkedList(node.next); // node.next = rest of the linkedList
node.next.next = node; // consider node as the first part of linkedList
node.next = null;
}
}
The simplest method that I can think of it's:
public static <T> void reverse( LinkedList<T> list )
{
if (list.size() <= 1) {
return;
}
T first = list.removeFirst();
reverse( list);
list.addLast( first );
}
i just found this difficult interview question online and I was hoping someone could help me make sense of it. It is a generic question...given a singly linked list, swap each element of the list in pairs so that 1->2->3->4 would become 2->1->4->3.
You have to swap the elements, not the values. The answer should work for circular lists where the tail is pointing back to the head of the list. You do not have to check if the tail points to an intermediate (non-head) element.
So, I thought:
public class Node
{
public int n; // value
public Node next; // pointer to next node
}
What is the best way to implement this? Can anyone help?
I agree with #Stephen about not giving the answer (entirely), but I think I should give you hints.
An important thing to understand is that Java does not explicitly specify pointers - rather, whenever a non-primitive (e.g. not char, byte, int, double, float, long, boolean, short) is passed to a function, it is passed as a reference. So, you can use temporary variables to swap the values. Try to code one yourself or look below:
public static void swapNodeNexts(final Node n1, final Node n2) {
final Node n1Next = n1.next;
final Node n2Next = n2.next;
n2.next = n1Next;
n1.next = n2Next;
}
Then you'll need a data structure to hold the Nodes. It's important that there be an even number of Nodes only (odd numbers unnecessarily complicate things). It's also necessary to initialize the nodes. You should put this in your main method.
public static final int NUMPAIRS = 3;
public static void main(final String[] args) {
final Node[] nodeList = new Node[NUMPAIRS * 2];
for (int i = 0; i < nodeList.length; i++) {
nodeList[i] = new Node();
nodeList[i].n = (i + 1) * 10;
// 10 20 30 40
}
// ...
}
The important part is to set the Node next values. You can't just loop through with a for loop for all of them, because then the last one's next would throw an IndexOutOfBoundsException. Try to make one yourself, or peek at mine.
for (int i = 0; i < nodeList.length - 1; i++) {
nodeList[i].next = nodeList[i + 1];
}
nodeList[nodeList.length - 1].next = nodeList[0];
Then run your swap function on them with a for loop. But remember, you don't want to run it on every nodeā¦ think about it a bit.
If you can't figure it out, here is my final code:
// Node
class Node {
public int n; // value
public Node next; // pointer to next node
#Override
public String toString() {
return "Node [n=" + n + ", nextValue=" + next.n + "]";
}
}
// NodeMain
public class NodeMain {
public static final int NUMPAIRS = 3;
public static void main(final String[] args) {
final Node[] nodeList = new Node[NUMPAIRS * 2];
for (int i = 0; i < nodeList.length; i++) {
nodeList[i] = new Node();
nodeList[i].n = (i + 1) * 10;
// 10 20 30 40
}
for (int i = 0; i < nodeList.length - 1; i++) {
nodeList[i].next = nodeList[i + 1];
}
nodeList[nodeList.length - 1].next = nodeList[0];
// This makes 1 -> 2 -> 3 -> 4 -> 1 etc.
printNodes(nodeList);
for (int i = 0; i < nodeList.length; i += 2) {
swapNodeNexts(nodeList[i], nodeList[i + 1]);
}
// Now: 2 -> 1 -> 4 -> 3 -> 1 etc.
printNodes(nodeList);
}
private static void printNodes(final Node[] nodeList) {
for (int i = 0; i < nodeList.length; i++) {
System.out.println("Node " + (i + 1) + ": " + nodeList[i].n
+ "; next: " + nodeList[i].next.n);
}
System.out.println();
}
private static void swapNodeNexts(final Node n1, final Node n2) {
final Node n1Next = n1.next;
final Node n2Next = n2.next;
n2.next = n1Next;
n1.next = n2Next;
}
}
I hope you were able to figure out at least some of this with guidance. More importantly, however, it's important that you understand the concepts here. If you have any questions, just leave a comment.
Simple recursive solution in Java:
public static void main(String[] args)
{
Node n = new Node(1);
n.next = new Node(2);
n.next.next = new Node(3);
n.next.next.next = new Node(4);
n.next.next.next.next = new Node(5);
n = swap(n);
}
public static Node swap(Node n)
{
if(n == null || n.next == null)
return n;
Node buffer = n;
n = n.next;
buffer.next = n.next;
n.next = buffer;
n.next.next = swap(buffer.next);
return n;
}
public static class Node
{
public int data; // value
public Node next; // pointer to next node
public Node(int value)
{
data = value;
}
}
Methods needed to run this program :
public static void main(String[] args) {
int iNoNodes = 10;
System.out.println("Total number of nodes : " + iNoNodes);
Node headNode = NodeUtils.createLinkedListOfNElements(iNoNodes);
Node ptrToSecondNode = headNode.getNext();
NodeUtils.printLinkedList(headNode);
reversePairInLinkedList(headNode);
NodeUtils.printLinkedList(ptrToSecondNode);
}
Approach is almost same, others are trying to explain. Code is self-explainatory.
private static void reversePairInLinkedList(Node headNode) {
Node tempNode = headNode;
if (tempNode == null || tempNode.getNext() == null)
return;
Node a = tempNode;
Node b = tempNode.getNext();
Node bNext = b.getNext(); //3
b.setNext(a);
if (bNext != null && bNext.getNext() != null)
a.setNext(bNext.getNext());
else
a.setNext(null);
reversePairInLinkedList(bNext);
}
Algo(node n1) -
keep 2 pointers n1 and n2, at the current 2 nodes. n1 --> n2 --->...
if(n1 and n2 link to each other) return n2;
if(n1 is NULL) return NULL;
if(n2 is NULL) return n1;
if(n1 and n2 do not link to each other and are not null)
change the pointer of n2 to n1.
call the algorthm recursively on n2.next
return n2;
Code (working) in c++
#include <iostream>
using namespace std;
class node
{
public:
int value;
node* next;
node(int val);
};
node::node(int val)
{
value = val;
}
node* reverse(node* n)
{
if(n==NULL) return NULL;
node* nxt = (*n).next;
if(nxt==NULL) return n;
if((*nxt).next==n) return nxt;
else
{
node* temp = (*nxt).next;
(*nxt).next = n;
(*n).next = reverse(temp);
}
return nxt;
}
void print(node* n)
{
node* temp = n;
while(temp!=NULL)
{
cout<<(*temp).value;
temp = (*temp).next;
}
cout << endl;
}
int main()
{
node* n = new node(0);
node* temp = n;
for(int i=1;i<10;i++)
{
node* n1 = new node(i);
(*temp).next = n1;
temp = n1;
}
print(n);
node* x = reverse(n);
print(x);
}
The general approach to take is to step through the list, and on every other step you reorder the list nodes by assigning the node values.
But I think you will get more out of this (i.e. learn more) if you actually design, implement and test this yourself. (You don't get a free "phone a friend" or "ask SO" at a job interview ...)
Yep, write an iterative routine that progresses two links in each iteration. Remember the link from the previous iteration so that you can back-patch it, then swap the current two links. The tricky parts are getting started (to a small extent) and knowing when to finish (to a larger one), especially if you end up having an odd number of elements.
public static Node swapInPairs(Node n)
{
Node two;
if(n ==null ||n.next.next ==null)
{
Node one =n;
Node twoo = n.next;
twoo.next = one;
one.next =null;
return twoo;
}
else{
Node one = n;
two = n.next;
Node three = two.next;
two.next =one;
Node res = swapInPairs(three);
one.next =res;
}
return two;
}
I wrote the code at atomic level. So i hope it is self explanatory. I tested it. :)
public static Node swapPairs(Node start)
{
// empty or one-node lists don't need swapping
if (start == null || start.next == start) return start;
// any list we return from here on will start at what's the second node atm
Node result = start.next;
Node current = start;
Node previous = null; // so we can fix links from the previous pair
do
{
Node node1 = current;
Node node2 = current.next;
// swap node1 and node2 (1->2->? ==> 2->1->?)
node1.next = node2.next;
node2.next = node1;
// If prev exists, it currently points at node1, not node2. Fix that
if (previous != null) previous.next = node2;
previous = current;
// only have to bump once more to get to the next pair;
// swapping already bumped us forward once
current = current.next;
} while (current != start && current.next != start);
// The tail needs to point at the new head
// (if current == start, then previous is the tail, otherwise current is)
((current == start) ? previous : current).next = result;
return result;
}
//2.1 , 2.2 Crack the code interview
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct Node{
int info;
struct Node *next;
};
struct Node *insert(struct Node *head,int data){
struct Node *temp,*ptr;
temp = (struct Node*)malloc(sizeof(struct Node));
temp->info=data;
temp->next=NULL;
if(head==NULL)
head=temp;
else{
ptr=head;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=temp;
}
return head;
}
struct Node* reverse(struct Node* head){
struct Node *current,*prev,*next;
current = head;
prev=NULL;
while(current!=NULL){
next=current->next;
current->next = prev;
prev=current;
current=next;
}
head=prev;
return head;
}
/*nth till last element in linked list*/
void nthlastElement(struct Node *head,int n){
struct Node *ptr;
int last=0,i;
ptr=head;
while(ptr!=NULL){
last++;
//printf("%d\n",last);
ptr=ptr->next;
}
ptr=head;
for(i=0;i<n-1;i++){
ptr=ptr->next;
}
for(i=0;i<=(last-n);i++){
printf("%d\n",ptr->info);
ptr=ptr->next;
}
}
void display(struct Node* head){
while(head!=NULL){
printf("Data:%d\n",head->info);
head=head->next;
}
}
void deleteDup(struct Node* head){
struct Node *ptr1,*ptr2,*temp;
ptr1=head;
while(ptr1!=NULL&&ptr1->next!=NULL){
ptr2=ptr1;
while(ptr2->next!=NULL){
if(ptr1->info==ptr2->next->info){
temp=ptr2->next;
ptr2->next=ptr2->next->next;
free(temp);
}
else{
ptr2=ptr2->next;
}
}
ptr1=ptr1->next;
}
}
void main(){
struct Node *head=NULL;
head=insert(head,10);
head=insert(head,20);
head=insert(head,30);
head=insert(head,10);
head=insert(head,10);
printf("BEFORE REVERSE\n");
display(head);
head=reverse(head);
printf("AFTER REVERSE\n");
display(head);
printf("NTH TO LAST\n");
nthlastElement(head,2);
//printf("AFTER DUPLICATE REMOVE\n");
//deleteDup(head);
//removeDuplicates(head);
//display(head);
}
public class Node
{
public int n; // value
public Node next; // pointer to next node
}
Node[] n = new Node[length];
for (int i=0; i<n.length; i++)
{
Node tmp = n[i];
n[i] = n[i+1];
n[i+1] = tmp;
n[i+1].next = n[i].next;
n[i].next = tmp;
}