Matrix of doubly linked nodes - java

i'm trying to make a 11 x 11 matrix of nodes doubly linked nodes in Java but i have a problem, i linked the nodes to right, left and down node but when i try to link to the up node i just can't and when i try to get node.up for example, i got a null instead of getting an int(which i should get).
Anyway, here is my code hoping someone can help me. I guess the error may be in void linkUp().
public class CazadorPresa {
// node of linked list
static class Node {
int no;
Node right;
Node down;
Node left;
Node up;
int xpos,ypos;
public boolean hunter,prey,crossed,blocked;
};
// returns head pointer of linked list
// constructed from 2D matrix
static Node construct(int arr[][], int i, int j, int m, int n) {
// return if i or j is out of bounds
if (i > n - 1 || j > m - 1)
return null;
// create a new node for current i and j
// and recursively allocate its down and
// right pointers
Node temp = new Node();
temp.no = arr[i][j];
temp.xpos = j;
temp.ypos = i;
temp.blocked = false;
temp.crossed = false;
temp.hunter = false;
temp.prey = false;
temp.right = construct(arr, i, j + 1, m, n);
temp.down = construct(arr, i + 1, j, m, n);
return temp;
}
// utility function for displaying
// linked list data
static void display(Node head) {
// pointer to move right
Node Rp;
// pointer to move down
Node Dp = head;
// loop till node->down is not NULL
while (Dp != null) {
Rp = Dp;
// loop till node->right is not NULL
while (Rp != null) {
System.out.print(Rp.no + " ");
Rp = Rp.right;
}
System.out.println();
Dp = Dp.down;
}
}
// link left
static void linkLeft(Node head) {
Node Rp;
Node Dp = head;
Node auxL= head;
// loop till node->down is not NULL
while (Dp != null) {
Rp = Dp;
// loop till node->right is not NULL
while (Rp != null) {
if(Rp==Dp){
}else{
Rp.left = auxL;
auxL = Rp;
}
Rp = Rp.right;
}
Dp = Dp.down;
}
}
// link UP
static void linkUp(Node head) {
// pointer to move right
Node Rp;
// pointer to move down
Node Dp = head;
Node aux;
// loop till node->down is not NULL
while (Dp != null) {
Rp = Dp;
// loop till node->right is not NULL
while (Rp != null) {
aux = Rp.down;
if(aux==null){
}else{
aux.up = Rp;
}
Rp = Rp.right;
}
Dp = Dp.down;
}
}
static void hunter(Node head,int x, int y) {
Node arr,aba,izq,der;
boolean out = false;
// pointer to move right
Node Rp;
// pointer to move down
Node Dp = head;
// loop till node->down is not NULL
while (Dp != null) {
Rp = Dp;
// loop till node->right is not NULL
while (Rp != null) {
if(Rp.xpos==x-1 && Rp.ypos==y-1){
Rp.hunter = true;
arr=Rp.up;
if(arr==null){
System.out.println("No link up");
}else{
System.out.println(arr.no);
}
aba=Rp.down;
izq=Rp.left;
der=Rp.right;
System.out.println(" "+izq.no+" "+aba.no+" "+der.no);
out=true;
}
if(out==true){
break;
}
Rp = Rp.right;
}
if(out==true){
break;
}
Dp = Dp.down;
}
}
// driver program
public static void main(String args[]) {
// 2D matrix
int arr[][]= new int[11][11];
int no=1;
for(int i=0;i<11;i++){
for(int j=0;j<11;j++){
arr[i][j] = no;
no=no+1;
}
}
int m = 11, n = 11;
Node head = construct(arr, 0, 0, m, n);
linkUp(head);
linkLeft(head);
display(head);
System.out.println("I should get: 38 48 60 50 but i get: ");
hunter(head,5,5);
}
}

The problem is in the use of recursion to construct the grid of Nodes. When you do:
temp.right = construct(arr, i, j + 1, m, n);
temp.down = construct(arr, i + 1, j, m, n);
You're actually creating multiple versions of the grid, each one overwriting right and down linked Nodes that have already been created. For example, it should be the case that after construction, for a given node:
node.right.down == node.down.right
but given how the grid is constructed this will not be the case, which then causes problems when you come to try to link them up. You can see how bad the problem is by considering that for an 11x11 grid you should be creating 121 Nodes, but I checked and you're actually creating 705,431!
Fortunately the fix is fairly straightforward. Create a 2d array of Nodes and hook up them up directly:
public static void main(String args[]) {
// 2D matrix
Node arr[][]= new Node[11][11];
int m = 11, n = 11;
int no=1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
arr[i][j] = new Node();
arr[i][j].no = no;
arr[i][j].xpos = j;
arr[i][j].ypos = i;
no=no+1;
}
}
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
arr[i][j].up = (i>0) ? arr[i-1][j] : null;
arr[i][j].left = (j>0) ? arr[i][j-1] : null;
arr[i][j].down = (i+1<m) ? arr[i+1][j] : null;
arr[i][j].right = (j+1<n) ? arr[i][j+1] : null;
}
}
Node head = arr[0][0];
display(head);
hunter(head,5,5);
}
}
Which produces:
38
48 60 50
Which I believe is the output you were expecting.

Related

How do I insert an Item at a certain Index in a Linked 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 to create 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 execute this method nothing happens. The item that I try to add to a specific index never gets added. Does someone know what I did wrong? and How to fix it?
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) {
prev = temp;
temp = temp.nextNode;
i++;
}
if (index == i) {
Node newItem = new Node(item, null);
prev.nextNode = newItem;
newItem.nextNode = temp;
}
}
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;
}
}
}
}
There are a few issues, but you are most of the way there, you simply need to move the if statement if (index == i) {Node newItem... } inside of your 'for' loop like this:
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) {
prev = temp;
//Make sure the next node is not null
if (temp.nextNode != null) {
temp = temp.nextNode;
}
//Move the if check here inside the for loop, but before i++
if (index == i) {
Node newItem = new Node(item, null);
prev.nextNode = newItem;
//Make sure the next node is not null
if (temp.nextNode != null) {
newItem.nextNode = temp;
}
}
//now advance the index after the above
i++;
}
}
Note that your code had an error, which has been fixed by checking that the next node is not null.
We can see the updated method works by inserting 999 after index 2:
1. Insert At
2. toString
1
Insert an Item to a certain Index on the List
2 999
1. Insert At
2. toString
2
toString
[5, 18, 8, 999, 11, 11, 1, 19, 3, 1, 10]
1. Insert At
2. toString
If you want the item to be inserted at index 2 instead, then adjust the order and put the if statement before prev = temp;

My System.currentTimeMillis() method calls are not registering properly. I don't understand why they stay at 0.0

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.

Having some trouble using a Linked List and passing elements to the Node

In this specific instance, it takes into account two occasions. One where I'm trying to place a node in the beginning of the Linked List and one where I'm trying to place it in the middle or at the end. Here is my Node Class. If you look at my INSERT method, the part that is not working is:
Node newNode = new Node();
newNode.setExponent(element);
class Node {
private int coefficient;
private int exponent;
private Node link;
// Constructor: Node()
Node(int c, int e) {
// Sets coefficient to c, exponent to e, and link to null
coefficient = c;
exponent = e;
link = null;
}
// Inspectors: getCoefficient(), getExponent(), getLink()
public int getCoefficient() {
// Returns coefficient
return coefficient;
}
public int getExponent() {
// Returns exponent
return exponent;
}
public Node getLink() {
// Returns link
return link;
}
// Modifiers: setCoefficient(), setExponent(), setLink()
public void setCoefficient(int c) {
// Sets coefficient to c
coefficient = c;
}
public void setExponent(int e) {
// Sets exponent to e
exponent = e;
}
public void setLink(Node n) {
// Sets link to n
link = n;
}
}// Ends Node Class
Here is where I'm trying to insert to my Linked List along with some other methods in the class that should help give you an idea of how my code looks.
class List {
private Node head; // Points to first element of the list
private int count; // number of elements in the list
// Constructor:
List() {
// Sets head to null and count to zero
head = null;
count = 0;
}
// Inspectors:
// Returns the number of elements in the list
public int size() {
return count;
}
// Modifiers:
// Inserts element at index in the list. Returns true if successful
public boolean insert(int index, Node element) {
if (index < 0 || index > count)return false;
if (index == 0) {
Node newNode = new Node();
newNode.setExponent(element);
count++;
newNode.setLink(head);
head = newNode;
return true;
}
Node walker = head;
for (int i = 1; i < (index - 1); i++)
walker = walker.getLink();
Node newNode = new Node();
newNode.setExponent(element);
newNode.setLink(walker.getLink());
walker.setLink(newNode);
count++;
return true;
}
Try this:
Assumption: You are trying to insert a Node element into the index of LinkedList
Your insert method with modification.
public boolean insert(int index, Node element) {
//if (index < 0 || index > count)
if (index < 0 || index > count + 1) return false;
if(head == null) {
head = element;
return true;
}
if (index == 0) {
//Node newNode = new Node();
//newNode.setExponent(element);
count++;
element.setLink(head);
//newNode.setLink(head);
head = element;
//head = newNode;
return true;
}
Node walker = head;
//for (int i = 0; i < (index - 1); i++)
for (int i = 1; i < index; i++) {
walker = walker.getLink();
}
//Node newNode = new Node();
//newNode.setExponent(element);
element.setLink(walker.getLink());
//newNode.setLink(walker.getLink());
//walker.setLink(newNode);
walker.setLink(element);
count++;
return true;
}
Sample Test Case:
print method:
void print() {
Node travel = head;
while(travel!= null) {
System.out.println(travel.getExponent() + " " + travel.getCoefficient());
travel = travel.getLink();
}
}
Main method:
public static void main(String args[]) {
Node n1 = new Node(1,2);
List l = new List();
l.insert(0,n1);
Node n2 = new Node(3,2);
l.insert(1,n2);
Node n3 = new Node(4,5);
l.insert(0,n3);
l.print();
}

Unresolved compilation error

Here's my code for insertion of a node in a compressed suffix trie :
public class tree {
char a[] = new char[10];
a[0]='b';
a[1]='a';
a[2]='n';
a[3]='a';
a[4]='n';
a[5]='a';
a[6]=' ';
protected node root;
public tree() {
this.root = new node();
}
public void inorder(node n) {
if (n.getChildren().next != null) {
inorder(n.getChildren().next.getChild());
}
System.out.println(n.getStart() + n.getEnd());
if (n.getChildren().next.next != null) {
inorder(n.getChildren().next.next.getChild());
}
}
public void insert(node n, node r) {
while (n.getStart() != 6) {
if (r.getChildren().next == null) {
//when the tree is empty :
n.setParent(r);
n.getChildren().setNext(null);
link newn = new link();
newn.setNext(null);
newn.setChild(n);
r.getChildren().next = newn;
node newnode = n;
newnode.setStart(n.getStart() + 1);
insert(newnode, r);
}
else {
// count is the node where we begin checking for same letters :
node count = r.getChildren().next.getChild();
// l is the linked list containing children of the node :
link l = r.getChildren().next;
while ((a[count.getStart()] != a[n.getStart()])
|| (l.next != null)) {
l = l.next;
count = l.getChild();
}
// create a new link node corresponding to the node to be inserted
// only for the case when we reach the end of the list :
link h = new link();
h.setNext(null);
h.setChild(n);
// we have reached the end of the linked list :
if ((a[count.getStart()] != a[n.getStart()])
&& (l.next == null)) {
if (n.getStart() != n.getEnd()) {
l.setNext(h);
h.setNext(null);
h.setChild(n);
n.setParent(r);
n.getChildren().setNext(null);
node newnode = n;
newnode.setStart(n.getStart() + 1);
insert(newnode, r);
}
else {
l.setNext(h);
h.setNext(null);
h.setChild(n);
n.setParent(r);
n.getChildren().setNext(null);
node newnode = new node();
newnode.setStart(count.getStart() + 1);
newnode.setEnd(n.getEnd());
}
}
// if we have found an element whose characters
// match that of the node:
else {
link kids = count.getChildren();
int x = count.getStart();
int y = n.getStart();
int p = count.getEnd();
int q = n.getEnd();
int t1 = count.getStart();
int t2 = n.getStart();
int length = p - x + 1;
int same = 1;
while (a[x + 1] == a[y + 1]) {
x++;
y++;
same++;
}
int g = length - same;
//modifying the node r:
count.setStart(t1);
count.setEnd(x);
// creating the 2 new nodes to be inserted below count if
// count initially doesnt have any children :
node kid1 = new node();
kid1.setStart(x + 1);
kid1.setEnd(p);
kid1.getChildren().setNext(null);
node kid2 = new node();
kid2.setStart(y + 1);
kid2.setEnd(q);
// creating 2 new link nodes to be inserted in
// the children list of count :
link k1 = new link();
link k2 = new link();
k1.setChild(kid1);
k2.setChild(kid2);
k1.setNext(k2);
k2.setNext(null);
//changing relationships :
kid1.setChildren(kids);
kid1.setParent(count);
count.getChildren().next.setNext(k1);
while (kids.next != null) {
kids.next.getChild().setParent(kid1);
kids = kids.next;
}
insert(kid2, count);
}
}
}
}
public static void main(String[] args) {
tree t = new tree();
node banana = new node();
banana.setStart(0);
banana.setEnd(7);
banana.getChildren().setNext(null);
t.insert(banana, t.root);
//inorder(tree.root);
}
}
When I run it in Eclipse, it says that it has some unresolved compilation problem.
Can you please help me sort this out? Thanks.
You cannot have non-declarative statements in the class block.
a[0]='b';
a[1]='a';
...
All these array assignments belong in a method, constructor or static initializer block. Alternatively, if adjusting the length or your array, is an option you could simply use:
char a[] = "banana".toCharArray();

Singly linked list in java

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;
}

Categories