Doubly Linked List - InsertAfter - Java - java

First of all, let me say that this is an assignment for a class where we have been tasked with writing our own doubly linked list class and cannot use anything from Java SE (e.g. the LinkedList class). We have to make our code work with a provided driver class. I am not asking for anyone to do the homework for me, I am simply asking for some kind of clarification as to how exactly to implement these methods, since I have struggled with this on and off over the past few days.
We have been provided with an Interface, textEditor.java that provides methods which will be utilized by the driver class, driver.java. These methods include the typical insert, et. al. but my concern is the insertAfter(int lineNum, E line) method and its counterpart, insertBefore. I have not been able to get these to work because comparing int to E, despite my best efforts and reading through several Java texts for guidance.
Below is the code in the DoublyLinkedList.java file, as provided at onset. I would like to know how I can implement some kind of indexing and checking in order to be able to make an insertion following or preceding the line entered by the user/driver class.
public class DoublyLinkedList<E> implements TextEditor<E>
{
Node<E> head, tail;
public DoublyLinkedList()
{
head = null;
tail = null;
}
public boolean isEmpty()
{
return (head == null);
}
public void insert(E line)
{
}
public void insertAfter(int lineNum, E line)
{
}
public void insertBefore(int lineNum, E line) throws IndexOutOfBoundsException
{
}
public void deleteByPosition(int position)
{
}
public void printNode(int position)
{
}
public void printAllNodes()
{
}
}
I have not been able to do this, and having tried several things over several hours, I have given up hope of being able to do it. If I don't find help here or still can't get these methods to work, I will be speaking with my instructor. It may simply be that I am overthinking the problem, and I hope that that is the case.

I'm assuming that your Node class looks like this :
class Node<E> {
private Node next;
private E value;
[...]
}
You can add an attribute in your DoublyLinkedList class, in which you keep the number of Node that your list contains.
Then, if you want the Nth element of your list, you can do this :
private Node getNthElement(int n) {
Node node = head;
for (int i=0; i<n; i++) {
node = node.next;
}
return node;
}
These methods should also check if there are enough elements in the list, etc. But this is the main idea.

Related

Traversing,Insertion and Deletion in LinkedList data structure in java [duplicate]

This question already has answers here:
How to implement a Linked List in Java? [duplicate]
(7 answers)
Closed 6 years ago.
I am new to data structures. I am very curious to learn data structures, but i didnt find any healthy tutorial for that so I am posting it here thinking someone would help me. I know theory of linked list but m totally blank while implementation. If Someone can make me understand how it works that would be really helpful for me.Like, how to traverse through Linked List ,insert and delete. Please provide me a running code so that its easy for me to understand.
I KNOW there are lot of peoples who will think to mark this question as a duplicate and downvote this. Rather than finding mistakes if you guys provide me a good solution that would be really Helpful. Thanks.
Simple implementation of a linked list showing append, insert, delete and iterate. There are inefficiencies, they're for you to figure out :) Go do some research to see how to make it better.
public class LinkedList {
public static class Node {
private Object data;
private Node next = null;
public Node(Object data) {
this.data = data;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public Object getData() {
return data;
}
}
public static void iterate(Node n) {
while (n != null) {
System.out.println(n.getData());
n = n.getNext();
}
}
public static void insert(Node newNode, Node after) {
newNode.setNext(after.getNext());
after.setNext(newNode);
}
public static void delete(Node toDelete, Node root) {
Node n = root;
while (n.getNext() != toDelete) {
n = n.getNext();
}
n.setNext(toDelete.getNext());
}
public static void main(String[] args) {
Node a = new Node("a");
Node b = new Node("b");
Node c = new Node("c");
// append
a.setNext(b);
b.setNext(c);
// iterate
System.out.println("Initial list");
iterate(a);
// insert d after b
Node d = new Node("d");
insert(d, b);
// iterate again
System.out.println("After insert");
iterate(a);
// delete d
delete(d, a);
// iterate again
System.out.println("After delete");
iterate(a);
}
}
Well to start, if you go on youtube and search up Derek Banas you will find a great video just on LinkedLists, and how to implement them. He talks kind of fast, but the content is very well taught in my opinion. Just following along in his videos and after the video I think you will have a better understanding.
https://www.youtube.com/watch?v=195KUinjBpU

Using a global variable versus passing a variable around while writing a recursive algorithm

I have a method to flatten a Binary search tree. I have two approaches for it:
• Using a variable and passing it around
import java.util.*;
public class BST {
private Node root;
private class Node {
private int val; // associated data
private Node left, right; // left and right subtree
public Node(int val) {
this.val = val;
}
}
public ArrayList<Integer> flattenTree(){
ArrayList<Integer> list = new ArrayList<>();
flattenTree(root, list);
return list;
}
public void flattenTree(Node node, ArrayList<Integer> list)
{
if (node == null)
return;
flattenTree(node.left, list);
list.add(node.val);
flattenTree(node.right, list);
}
public static void main(String[] args) {
BST bst = new BST();
bst.add(5);
bst.add(1);
bst.add(0);
bst.add(3);
System.out.println(bst.flattenTree());
}
}
• Using a class variable:
import java.util.*;
public class BST {
private Node root;
ArrayList<Integer> list = new ArrayList<>();
private class Node {
private int val; // associated data
private Node left, right; // left and right subtree
public Node(int val) {
this.val = val;
}
}
public ArrayList<Integer> flattenTree(){
flattenTree(root);
return list;
}
public void flattenTree(Node node)
{
if (node == null)
return;
flattenTree(node.left);
list.add(node.val);
flattenTree(node.right);
}
public static void main(String[] args) {
BST bst = new BST();
bst.add(5);
bst.add(3);
bst.add(1);
bst.add(0);
bst.add(3);
bst.add(3);
bst.printInorder();
System.out.println(bst.flattenTree());
}
}
In both cases I get:
sgupta$ java BST
[0, 1, 3, 5]
I'm a beginner to java (high school) and wondering what the pros and cons of each approach are.
The only one I can think of is that approach #2 has less messy code by not having to pass the list around.
To add to #caskey's points, I'd like to point out two other major advantages of the first version of the code.
First, the code that accepts an explicit list is harder to use incorrectly. If you call the second version of the code, you need to
make sure no one else is calling the method in a parallel thread,
make sure that the list variable has been initialized,
make sure that the list doesn't already contain anything else, and
remember to read off the list when you're done with it.
If you forget to do any of these, your program will not behave as expected, but you won't get any compiler errors indicating this. This makes the code harder to use correctly and increases the chances that you'll get more bugs in your program.
Second, the first version has an easier description. The first version of the code can be described as "populate the given list with an inorder traversal of the tree." The second version is "appends to the existing contents of the list list an inorder traversal of the tree." It's harder to describe what this second one does, so the burden on the documentation is greater. Plus, it's harder for programmers reading the code for the first time to understand what it does.
Hope this helps!
The disadvantage, in general, to global variables is twofold.
1) you have only one global variable and so two copies of your code can't run at the same time (i.e., multiple threads).
2) The global variable can be modified in other places which your code might not expect.
Your first answer is the better engineered solution.
Good questions to ask:
Does the class have state it needs to hold onto?
If so, what is the state (i.e. the fields)?
Can you avoid state by passing arguments in method calls, which makes for easier to test code.

Get Exception in thread "main" java.lang.NullPointerException with LinkedList

Simple Linked List
public class List_manager {
Entry first;
Entry last;
public void add(String el) {
if (isEmpty()) { first=new Entry(el); last=first; return; }
new Entry(el,last);
}
public String get() {
Entry temp=first;
first=first.next;
return temp.data;
}
public boolean isEmpty() {
return first==null;
}
private class Entry {
String data;
Entry next;
public Entry(String data,Entry to) {
this.data=data;
to.next=this;
to=this;
}
public Entry(String data) {
this.data=data;
}
}
}
#The main class#
I added 3 element and list contains only 2... why?
public class Main {
public static void main(String[] args) {
List_manager l=new List_manager();
l.add("1");
l.add("2");
l.add("3");
System.out.println(l.get());
System.out.println(l.get()); // Why here output: "3"??
System.out.println(l.get()); // here is an error occurs
}
}
I really don`t get why list contains 2 elements?
Why it ignores 2nd added element?
to=this; This sentence have no influence on variable 'last', because veriable 'to' is formal parameter, while variable 'last' is actual parameter. So, when you executed this sentence "to = this;" the value of
variable 'last' was not changed to next.That's mean variable 'last' always pointed to the first element.
my change is : new Entry(el,last); --> last = new Entry(el,last);
Things look better.
Think about what your get method is doing. You already noticed some aberrant behavior with it.
public String get() {
Entry temp=first;
first=first.next;
return temp.data;
}
What happens the first time I call this?
temp gets whatever first is pointing to
first is moved to its next element (RED FLAG)
temp's data is returned...
One problem is that you're moving your head reference around - this is a bad idea, since it means that you can never access the true first element in your list ever again.
Now on its own, even with this implementation, you should still be able to get the first element.
The above was just a red herring - although you should not be moving your head pointer around. This is the real problem. What happens on subsequent add calls to your list?
public void add(String el) {
if (isEmpty()) {
first = new Entry(el);
last = first;
return;
}
new Entry(el,last);
}
Only the first element inserted and the last element inserted are respected. All other entries after next are overwritten.
I suggest that you use a debugger to figure this one out, as it stems from a misunderstanding of a good approach to do this. You only want to insert things through your tail pointer once you have one element. Doing this through object creation only causes heartache and confusion.
For posterity, I'll leave you with a sample, verbatim implementation I wrote for a singly linked list implementation I did a while back. It describes a more viable approach to inserting into a list.
public void insert(E data) {
Node<E> candidate = new Node<>(data);
if(head == null) {
head = candidate;
tail = head;
} else {
tail.setNext(candidate);
tail = tail.getNext();
}
size = size + 1;
}

How to use Comparable as a Generic parameter in a Class

I have a home work in a data structures course, the question is:
Implementation of doubly-linked list class.
the methods:
display()
length() or size()
insertSorted(Comparable)
insertToEnd(Comparable)
insertToHead(Comparable)
delete(Comparable)
boolean search(Comparable)
You must do this in JAVA
Create an application layer to test your class and its methods.
Compress all of your source files into a file and rename it as CS214HW1_first_lastName.zip Put your name in the filename. If needed, add a ReadMe.txt file for extra information such as compilation.
I implemented everything correctly and the code is working fine, but I used for example: insertSorted(int) instead of insertSorted(Comparable), because I didn't know how to do it.
I searched online, and read the JAVA documentation for (Comparable) but it is not enough :(
Can anybody help, please it is very important?
Here's some of my code, I can't write it all, cuz I don't want my friends to get the same code.
I will take zero if there is same code.
Code:
class DLL {
class Node {
Node next;
Node prev;
int data;
Node() {
next = null;
prev = null;
data = 0;
}
Node(int dt) {
next = null;
prev = null;
data = dt;
}
}
Node head;
void insertToHead(int dt) {
if (head == null) {
head = new Node(dt);
}
else {
head.prev = new Node(dt);
head.prev.next = head;
head = head.prev;
}
}
public static void main(String args[]) {
DLL dll = new DLL();
dll.insertToHead(1);
dll.insertToHead(2);
dll.insertToHead(3);
}
}
Please, somebody, tell me what to change in the beginning of the class.
are we gone use extends or implements Comparable<E> or what!
and what changes should i do the method insertToHead(Comparable)
what changes should i do to the main.
You would probably like to look into how generics work as well. The basic idea is that you would like to set up your class so that it will not know exactly the specific type of object but can be given some hint at the types of things it can expect of a declared generic type.
In your case, you would like to set up your list so that you can create linked lists of anything that can be compared. Java has a class for that which you have mention called Comparable<E> this tells Java that it will be able to call such methods as compareTo on the provided object.
More specifically to your closing questions:
Use the following style of class declaration MyClass<MyGenericType extends Comparable<MyGenericType>>. In your case DLL<E extends Comparable<E>>.
Switch the method arguments to accept E our declared generic type.
You should use the class Integer instead of the primitive type int, and change the creation of your list to DLL<Integer> dll = new DLL<Integer>().
Fully updated version of provided code:
public class DLL<E extends Comparable<E>> {
class Node {
Node next;
Node prev;
E data;
Node() {
next = null;
prev = null;
data = null;
}
Node(E dt) {
next = null;
prev = null;
data = dt;
}
}
Node head;
void insertToHead(E dt) {
if (head == null) {
head = new Node(dt);
}
else {
head.prev = new Node(dt);
head.prev.next = head;
head = head.prev;
}
}
public static void main(String args[]) {
DLL<Integer> dll = new DLL<Integer>();
dll.insertToHead(1);
dll.insertToHead(2);
dll.insertToHead(3);
}
}
This new implementation should provide a hint for how to proceed with some of the other homework tasks. For instance you can now compare objects just by their compareTo method which might useful for sorting hint hint.
That doc page gives a very good explanation for how to use this method. You should note that in their docs, they use a generic type called T instead of E, it really doesnt make a difference you can call it whatever you want provided it is unique to your program.
Edit:
An each hint in the sorting direction:
Ojbects which extend the Comparable class have a method which is called compareTo this method is set up so you can call:
object1.compareTo(object2);
this method returns an int which will be:
> 0 when object1 is greater than object2
= 0 when object1 is equal to object2
< 0 when object1 is less than object2
I don't want to give away too much as this is a homework assignment but here is my hint:
The way the above code sets up your classes, you would be able to tell the relationship between NodeA and NodeB by calling:
NodeA.data.compareTo(NodeB.data)
this will return an integer which gives your information according to the list above.
The <=,>=,== operators are likely found in the Integer class's compareTo method.
Something like:
public int compareTo(Object o) {
int otherNumber = ((Integer) o).intValue();
int thisNumber = this.intValue();
if (otherNumber > thisNumber) {
return 1;
} else if (otherNumber < thisNumber) {
return -1;
} else {
return 0;
}
}
but more likely they just do something like:
public int compareTo(Object o) {
return this.intValue() - o.intValue(); // possibly normalized to 1, -1, 0
}
See the Docs on Integer for more info on this.

Sorting a Linked List

Suppose I have the following dataset stored in a linkedlist (excluding the header):
ID | Name
1 | John
2 | Albert
3 | Simon
Now, I would like to sort the nodes according to, say, alphabetical order.
I would like to know how I can come up with my own sorting method without using Arrays (and similar stuff like Lists, Vectors, ArrayLists etc.) and without using a library sorting method (e.g. Collections.sort).
In other words, I would like to know the concept of sorting and how one should go about arranging the nodes in a systematic manner. It doesn't have to be efficient - it just has to work.
I'll be trying this out in Java but I would appreciate pseudocodes or tips / hints / other resources as well.
Thank you.
Addendum:
LinkedList.java
class LinkedList
{
private Node head; // first node in the linked list
private int count;
public int getCount()
{
return count;
}
public Node getHead()
{
return head;
}
public LinkedList()
{
head = null; // creates an empty linked list
count = 0;
}
public void deleteFromFront()
{
if (count > 0)
{
Node temp = head;
head = temp.getLink();
temp = null;
count--;
}
}
public void AddToFront(Object cd)
{
Node newNode = new Node(cd);
newNode.setLink(head);
head = newNode;
count++;
}
public void RemoveAtPosition(int n)
{
int counter=1;
Node previous=null;
if(n==1)
deleteFromFront();
else if(n<=getCount())
for(Node j=head;j!=null;j=j.getLink())
{
if(counter==n&&previous!=null)
{
previous.setLink(j.getLink());
j.setLink(null);
}
previous=j;
counter++;
}
else
System.out.println("Unable to remove object at position "+n);
}
public void AddAtPosition(int n, Object cd)
{
int counter=1;
Node newNode=new Node(cd);
Node previous=null;
for(Node j=head;j!=null;j=j.getLink())
{
if(counter==n&&previous!=null)
{
newNode.setLink(j.getLink());
j.setLink(newNode);
}
previous=j;
counter++;
}
}
public void Swap(int n1, int n2)
{
// how do I swap nodes?
}
public void Sort()
{
// how do I sort nodes?
}
}
Node.java
public class Node {
private Object data;
private Node link;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLink() {
return link;
}
public void setLink(Node link) {
this.link = link;
}
public Node(Object data) {
this.data = data;
this.link = null;
}
}
If you want to do it yourself, insertion sort is really easy on linked lists. Create a new empty linked list, then insert all elements from the old one into it. Wikipedia has a C code example.
If you want to know how the JDK does it... I copies the list into an array, sorts that and copies it back.
You can use a bubble sort for a linked list but it will be slower, so it makes no sense, unless you like pain. ;)
I realize you say you don't want to use Collections.sort, but just to make sure: you do realize that Collections.sort allows you to implement for yourself the sorting order, right? If not, http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html (and many other resources) will provide info on that.
Otherwise, there are a lot of sorting algorithms you can implement. One of the easier to understand is Bubble Sort. http://en.wikipedia.org/wiki/Bubble_sort contains a good explanation of it, including a nice visualization of the different sorting steps.
But Bubble Sort isn't (at all) an efficient way of sorting. There are many other sorting algorithms (merge sort, insertion sort, quicksort, ... see Wikipedia's article on "Sorting algorithm" for an overview), and they each have their advantages and disadvantages. It depends on the data you're sorting which algorithm will fit best.
You can copy the list into an array and sort that. Otherwise, there are various sorting algorithms that can be used i.e. merge sort, bubble sort etc.
You can see this for merge sort implementation.
While not exactly the same, look at external sorts (where the data isn't loaded into memory; for example, you want to sort a file bigger than your RAM). They generally work by moving data between files, in a manner similar to how you might move nodes between linked lists.

Categories

Resources