Reverse LinkList whilst preserving original nodes - java

My teacher has assigned a program where I am to create a linked list of some random numbers. I am to create it from a list and then the second part of the assignment is to reverse it. The actual quote is
Write a Java method called reverseLinkedList() that will generate a
reversed linked-list from the linked-list that you create in problem
1. Your method should accept a linked-list as an input and return another linked list that has the node references in the reversed
order. Please do not print the original list in reverse. The idea is
to manipulate the node references so that the nodes are preserved in
same in order as they were originally created.
The code I have generated so far looks like
import java.util.*;
public class progassignment2
{
public static void main(String args[])
{
List<Integer> myList = new ArrayList<Integer>();
Random ran = new Random();
int ranNum;
for(int x = 0;x<5;x++)
{
ranNum = ran.nextInt(500);
myList.add(x,ranNum);
}
LinkedList<Integer> mylinklist = createLinkedList(myList);
System.out.println(mylinklist);
LinkedList<Integer> mylinklistrev = reverseLinkedList(mylinklist);
}
public static LinkedList createLinkedList(List<Integer> integerList)
{
LinkedList<Integer> linkedlist = new LinkedList<Integer>();
linkedlist.addAll(integerList);
return linkedlist;
}
public static LinkedList reverseLinkedList(LinkedList inputList)
{
for(int y = 0;y < inputList.size();y++)
{
inputList.addLast(inputList.pollFirst());
}
return inputList;
}
}
However I don't think I'm doing the assignment correctly, or that I understand what he is asking of me and unfortunately won't answer any questions and just cites "Read the assignment". Any help is greatly appreciated

What about:
public static LinkedList reverseLinkedList(List<Integer> inputList) {
LinkedList<Integer> reversedLinkedlist = new LinkedList<Integer>(inputList);
Collections.reverse(reversedLinkedlist);
return reversedLinkedlist;
}

Usually, exercises on linked lists do not make use of any built-in Java collection (like ArrayList, LinkedList, etc), but are instead meant to make you build your own collection type.
Your teacher probably wants you to build a very basic element, which would then become the building block of your own collection type: imagine an object where you can store a value and a reference to the following value in the list. In code:
class Node {
private int value;
private Node next;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
Each element points to the next one, and the end of the list is marked by the last node's next element being null.
By using objects like this, you'll be able to define your own linked list, without using any pre-defined Collection offered by Java.
You've surely heard about the stack data structure: by reading all the elements in your linked list and putting them inside a stack, once the list will be over, you're going to fetch the elements inside the stack; creating a linked list in the order of the elements pulled from the stack will solve your problem of inverting the linked list.

The idea is to manipulate the node references so that the nodes are
preserved in same in order as they were originally created.
You should create your own LinkedList. You are not allowed to use common ways of reversing like using recursion, stack ,modifications or any collections interface methods.
here is the link includes LinkedList reversing ways and solution:
class LinkedList {
Node head; // head of list
/* Linked list Node */
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
/* Function to print reverse of linked list */
void printReverse(Node head) {
if (head == null)
return;
// print list of head node
printReverse(head.next);
// After everything else is printed
System.out.print(head.data + " ");
}
/* Inserts a new Node at front of the list. */
public void push(int new_data) {
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
public static void main(String args[]) {
LinkedList llist = new LinkedList();
llist.push(4);
llist.push(3);
llist.push(2);
llist.push(1);
llist.printReverse(llist.head);
}
}

Related

How to print whole list after calling addfirst method?

How do i correct my addFirst method and also how can i make my removeFirst method work as it wont remove? How should i implement it?
public class LinkedList{
public static void main(String[] args) {
LinkedList l = new LinkedList();
l.addFirst("c");
//l.removeFirst("m");
l.addFirst("b");
System.out.println(l.first.data);
System.out.println(l.first.data);
}
public Node first;
static class Node {
String data;
Node next;
}
private void addFirst(String s){
Node newNode = new Node();
newNode.data=s;
newNode.next=first;
first= newNode;
}
private void removeFirst(String s){
//Node n1 = new Node();
first.next = null;
}
}
I want outcome to be :
b
c
but only b is printed.
You are printing the same value twice try this:
System.out.println(l.first.next.data);
In your linked list class, the first (or head) node will contain the next node so you'll have to call the first node and then call next nodes data.
Example:
LinkedList l = new LinkedList();
l.addFirst("c");
l.addFirst("b");
l.addFirst("z");
System.out.println(l.first.data);
System.out.println(l.first.next.data);
System.out.println(l.first.next.next.data);
Return linkedlist by each function except main.
After adding or removing node you have to return the linkedlist in main function then you can print whole linkedlist

implementing linked list using arrays

I am trying to implement a linked list in java using arrays as the underlying structure. However, I am not sure how to do insert an element in the array after an element and shift the array down by one
class linkedList{
char data[];
int next;
//constructor
public linkedList(int MAX){
data = new char[MAX];
}
public void insertFirst(char d){
if(data[next]==0){
data[next] = d;
next++;
}
else{
System.out.println("list is full");
}
}
public void insertAfter (char after ,char value){
next=0;
while(data[next] !=after){
next++;
}
char temp = data[next+1];
data[next+1] = value;
}
public void printList(){
for(int i=0;i<data.length;i++){
System.out.print(data[i]);
}
}
}
public class myLinkedList {
public static void main(String args[]) {
linkedList list = new linkedList(9);
list.insertFirst('T');
list.insertFirst('H');
list.insertFirst('L');
list.insertAfter('H', 'z');
list.printList();
}
}
Also would this be considered a linked list?
This is not a linked list. What you have is similar to an ArrayList, in that an array is used as the underlying data structure. A linked list is composed of a series of nodes, with each node linked to the next. The linked list is traversed by calling something like node.next() on the current node until the target or the end of the list is reached.
If you want to insert another element into your list structure after reaching the size limit, you will need to create a new array, copy the contents of the old array over, and insert the new element into the array. You can use System.arraycopy() to perform the copying or to shift items within the array.

Create new Node for Singly Linked List in Java

I am still learning Java, and currently working problems from Cracking the Coding Interview, and one of the problems on Chapter-2 (LinkedList) asks to remove duplicates from an unsorted linked List. I found a bunch of answers/solution on GitHub, but I would like to create my own Node, and write my own version.
What I have implemented so far is that I created Node class and write the function/method that can remove the duplicates from unsorted LinkedList, but when I try to test it, I tried to create the LinkedList in the main function, but I still have no idea how to figure it out. Can someone please help/guide me how to create a Singly LinkedList?
Basically, I create four nodes (fourth,third,second,head), and connect them all using the Node class.
Thanks in advance,
public class Node {
int data;
Node next;
public Node(int data, Node next){
this.data = data;
this.next = next;
}
public String toString(){
return data + "";
}
}
public class problem1 {
public void Remove_duplicates(Node head){
if(head == null){
return;
}
Node current = head;
while(current != null){
Node runner = current;
while(runner.next != null){
if(runner.next.data == current.data){
runner.next = runner.next.next;
}
else {
runner = runner.next;
}
}
current = current.next;
}
}
public static void main(String[] args) {
Node fourth = new Node(5,null);
Node third = new Node(3,fourth);
Node second = new Node(4,third);
Node head = new Node(3,second);
for(Node a: head){
// ERROR: saying can only iterate over an array (or) java.lang.Iterable
System.out.println(a.toString());
a = a.next;
}
}
}
Try another kind of loop e.g. while
Node head = new Node(3, second);
Node node = head;
while (node.next != null) {
System.out.println(node.toString());
node = node.next;
}
Like it explains it does not know how to iterate over your nodes.
Another approach for using the foreach would be to create an own class which implements the interface Iterable and does contain your LinkedList logic.
For the second approach I would suggest you to read the following: How can I implement the Iterable interface?

Bubble Sort Doubly Linked List Java

I am trying to create a bubble sort on a doubly linked linked list in Java but am getting Null Pointer Exception errors. I believe it to have an issue with when I call the getPrevious method on the head which of course has a value of null. However, I cannot think how to do the bubble sort without accessing the getPrevious method for the other nodes.
I can implement an if statement to check if its the head or tail of the list first, but I feel like there is a smarter way to do this.
I also have been unable to run a successful build of this, so am not even sure the code will work. If you have a different idea of how to implement this please let me know.
Any suggestions are welcome!
public static void bubbleSort(DoubleLinkedList list) //static method used to sort the linked list using bubble sort
{
int i = 0;
int j = 0;
Node currentNode = list.head;
Node previousNode = currentNode;
Node tempNext = currentNode;
Node tempPrevious = currentNode;
for(i=0; i<list.getSize(); i++)
{
for(j=0; j<list.getSize()-1; i++)
{
if(currentNode.getData() > currentNode.getNext().getData())
{
tempNext = currentNode.getNext().getNext();
tempPrevious = currentNode.getPrevious();
currentNode.getPrevious().setNext(currentNode.getNext());
currentNode.getNext().setNext(currentNode);
currentNode.setPrevious(currentNode.getNext());
currentNode.setNext(tempNext);
}
currentNode = currentNode.getNext();
}
}
}
So you have a double linked list. I assume each element contains some information... say an integer. It must also contain two pointers: one to the previous element and one to the next element.
Assuming this is true, notice that you don't have to modify the pointers because they already point from one element to another. all you have to do is sort the values of the list elements so that the first item in the list has the lowest value, the second has the second lowest value and so on.
You can do it like this:
public static void bubbleSort(DoubleLinkedList list) //static method used to sort the linked list using bubble sort {
int i = 0;
Node currentNode = list.head;
Node auxNode;
int foundChange = 1;
while(foundChange) {
foundChange = 0;
for(i=0; i<list.getSize()-1; i++) {
if (currentNode.getData() > currentNode.getNext().getData()) {
auxNode.setData(currentNode.getData());
currentNode.setData(currentNode.getNext.getData());
currentNode.getNext.setData(auxNode.getData());
foundChange = 1;
}
currentNode = currentNode.getNext();
}
}
If you haven't defined the setData method yet, then do so. It must be similar to getData, but it will set the data of an object to the value it gets as a parameter instead of returning the value of the data in that object.

Arraylist mapping to linkedlist nodes

I want to be able to access a certain node in my Doubly Linked List in O(1) time. I know that if i traverse the list to find a certain node it would take O(n) time so I want to map the nodes to an array list where I can access the nodes in O(1) time.
I'm really unsure how I would do this mapping. I would like to see an example of how this can be done.
Edit:
I would like to be able to access any node in the linked list so I can move the nodes around in O(1) time.
Example: Move node with ID 5 to end of list in O(1) time.
Edit 2: I uploaded a picture example of what I'm trying to accomplish
You can't do this with the built-in data structures ArrayList and LinkedList.
In general, it is not possible at all to have both of
O(1) indexing (by position in the list)
O(1) removing/adding/moving anywhere in the list.
The possibilities:
You can get to O(log(N)) for both these if you use a tree-based structure.
You can get to O(1) for indexing with a array-based structure, but then removing/adding in the middle takes O(n).
You can use a Hash-Map like-structure with adding/removing in O(1), but it only allows O(1) access by key, not access by index (other than iterating, i.e. O(n)). (This means, if you add/remove something in the middle, the indexes after it won't change.)
Even if you try to combine a linked list with an array, you'll have O(n) for removing/adding (since you still have to update the array).
Okay, with your added image to show what you want, it is doable. You are in fact reimplementing something like LinkedHashMap, but only with consecutive integer keys and with ability to manipulate the "Linked" part.
If your linked list consists of Node objects, you would have an ArrayList<Node>.
You would only add elements to the ArrayList when adding new nodes to the linked list, else use the ArrayList only for lookup.
Here is an example:
class FastIndexLinkedIntList<X> {
class Node {
Node next;
Node prev;
int key;
X value;
Node(int key, X val) { this.key = key; this.value = val; }
}
ArrayList<Node> indexedNodes = new ArrayList<Node>();
Node head;
Node tail;
public void add(X value) {
int key = indexedNodes.size();
Node node = new Node(key, value);
insertAtEnd(node);
indexedNodes.add(node);
}
private void insertAtEnd(Node n) {
if(tail == null) {
assert head == null;
head = n;
tail = n;
return;
}
n.prev = tail;
n.next = null;
tail.next = n;
tail = n;
}
private void removeNode(Node n) {
if(n.next == null) {
assert n == tail; // last node
tail = n.prev;
tail.next = null;
}
else {
n.next.prev = n.prev;
}
if(n.prev == null) {
assert n == head; // first node
head = n.next;
head.prev = null;
}
else {
n.prev.next = n.next;
}
}
public void moveNodeToEnd(int key) {
Node n = indexedNodes.get(key);
removeNode(n);
insertAtEnd(n);
}
}
You might want to add more operations here, but these are enough for the example in the question:
FastIndexedLinkedList<String> ll = new FastIndexedLinkedList<String>();
ll.add("0");
ll.add("1");
ll.add("2");
ll.add("3");
ll.moveNodeToEnd(2);
I'm not entirely sure of your purpose, do you simply wish to retrieve the object's index in O(1)?
This is how it would look:
LinkedList<Object> aList; // your LinkedList
Map<Object, Integer> mapper = new HashMap<Object, Integer>();
Object[] arr = aList.toArray();
for( int i = 0; i < arr.length; i++ ){
mapper.put( arr[i], i );
}
Now, if you want to find an object in your list, what you do is get its index from the mapper object with
mapper.get( o );
================================
Re: your edit
You can't (or there's none that I am aware of). You are essentially demanding the best of both worlds (linked lists and arrays).
LinkedHashMap: provides O(1) time and keys are doubly-linked list ordered.
Use the toArray() method to convert your LinkedList to an array for constant-time retrieval:
LinkedList.toArray(arr)

Categories