Inserting to sorted node - java

I'm working on a method which inserts the specified element at the correct position in the sorted list and I can insert the same element several times..however my method didn't insert the element and I couldn't figure out why it doesn't insert all the element in correct position! this is my code

It seems that you insert new item only if current is null. But when look closer in the above loop, the loop can exit and current is not null (first if)
so if first if is true the item does not get into the linked list

else{ //insert into sorted list
Node d=new Node(element);
Node current = head;
Node pre=null;
while(current!=null){
if(c.compare(current.item, element)>0){
break;
}
else{
pre=current;
current=current.next;
}
}
if(current == null && pre!=null){ //insert new tail
pre.next=d;
tail=d;
d.pre=pre;
size++;
return this;
}
else { //insert when compare is successful and node not at tail.
d.pre = pre;
pre.next = d;
current.pre = d;
d.next = current;
return this;
}
}

If you're looking for a way to create a sorted list that can have multiple elements, I'd recommend creating a class
public class SortedList<E> extends AbstractSequentialList<E> {
}
and implementing the necessary operations. You can look at Collections.sort() if you're looking to initially sort the list. Afterward, whenever you insert or remove from the list, you can do a binary search to find the correct location.
Another idea would be to create a class
public class Multiplicity<E> {
private E value;
private int numberOfDuplicates;
// etc. etc.
then, you could instead just use a SortedSet<Multiplicity<E>> and instead of inserting an element that's already there or removing one, instead, you increment or decrement the counter.

Related

Determining the Complexity of appending a value at the end of a List

As we know, to push an element at the front of list requires O(1) time. Now consider we want to put (or append) an element at the end of list. What is the complexity of this operation?
Now consider, to put an element at the end of list, we need to traverse the list up to the end (because of not having prev. pointer), requires O(n) time complexity. Will it possible to make this in O(1)?
I did some implementation, while appending value at the end, I am keeping the next place in pointer, where node can be inserted. Check out the following please:
import java.util.*;
class List{
int data;
List next;
List(int data){
this.data = data;
}
}
class Driver{
List head, temp;
Driver(){
head = null;
temp = head;
}
void push(int item){
if(head == null){
head = new List(item);
temp = head;
} else {
temp.next = new List(item);
temp = temp.next;
}
}
}
class AppendInList{
public static void main(String [] args){
Driver obj = new Driver();
obj.push(5);
obj.push(66);
}
}
I searched in SO, but I didn't get anything for my satisfaction! Correct me if I did some mistake!
You can push an element to the front of a linked list in O(1) time, if you save a reference to the front/head element in the linked list data structure.
Similarly, you could maintain a reference to the last element, using which you could add an element to the last in O(1) time. You would have to update the last pointer every time you add an element.
The data structure could look like below:
class List{
ListNode head;//ListNode class stores next reference and value of the node
ListNode tail;//last element
void pushToLast(ListNode newElement){
//TODO : Take care of corner cases
tail.next = newElement;
tail = newElement;
}
}

Subtracting a passed Linked List in the Method from the Calling Linked List

Essentially what this problem does is take in a Linked List as a parameter and subtracts its contents from the calling Linked List if the same contents exist in both. I have to do it this way (so no changing the parameters).
For instance: l1.subtractList(l2) would subtract the contents of l2 from l1.
The trouble here is that the calling Linked List has 2 of the same number and that number is also in the Linked List passed as a parameter. I only have to remove one instance of it as well.
I've managed to subtract everything but that duplicate number, but I'm not sure what I'm doing wrong. Keep in mind this is a very new subject to me, so I may be way off base. But I appreciate any and all help you may offer. Thanks.
public void subtractList(LinkedList list)
{
Node current = head;
Node<Integer> temp = list.getFirst();
Integer count = -1;
while (current != null)
if (current == temp){
count++;
list.listRemove(count);
temp = list.getFirst();
}
else
{
current = current.getNext();
}
}
What is listRemove method? Why do you need count? Just traverse the argument list and check if its element temp exists in the calling Linked List. You will need an outer loop traversing the list passed as argument and an inner loop iterating over the calling list to check the value of the element needing to be removed and to remove it if required
while(temp!=null)
{
while(current!=null){
//Check if element exists in list
//If yes, remove it from the calling list
}
//Repeat
temp = temp.getNext();
}

Inserting new object onto Linkedlist(of Strings) in alphabetical order without sorting

I'm wondering if this is possible in Java. I want to insert it into the correct spot alphabetically.
For example is the the LinkedList's (let's say it's called coollist) elements were : [Dusty, Gordon, Mayer, Popovic, Zechariah]
and I try to insert another String by doing:
coollist.add(d,Nyugen); //d is a a variable representing ant int which is the index
What can I do to make d the value that will insert it in alphabetical order, regardless of what's in the LinkedList? Can you guys help me out?
I hope this makes sense.
Following is one way to find the sorted index in LinkedList.
import java.util.*;
public class SortedLinkedListDemo {
public static void main (String [] args) {
List<String> list = new LinkedList<String> ();
list.add ("Dusty");
list.add ("Gordon");
list.add ("Mayer");
list.add ("Popovic");
list.add ("Zechariah");
list.add (getSortedIndex ("Nyugen", list), "Nyugen");
System.out.println ("List: "+list);
}
private static int getSortedIndex (String name, List<String> list) {
for (int i=0; i < list.size(); i++) {
if (name.compareTo(list.get(i)) < 0) {
return i;
}
}
// name should be inserted at end.
return list.size();
}
}
This will give the following output:
List: [Dusty, Gordon, Mayer, Nyugen, Popovic, Zechariah]
You can iterate though the list, searching for when the index produces a string that is greater than the argument. Then just insert behind that index. If this is a one-way linked list, you'll have to keep track of the previous node so you can update its fields.
Node newNode = new Node( stringToBeAdded ); //Create new node
if ( this.head == null ){ //list is empty, just insert
this.head = newNode; //Initialize head
}
else{
Node cur = this.head; //Start at the beginning of the list
Node prev = this.head; //just initialize the previous node to something
//keep going until found or at end of list
while( (stringToBeAdded < cur.data) && (cur != null) ){
prev = cur;
cur = cur.next;
}
prev.next = newNode;
if ( cur != null ){ //if we did not reach the end
newNode.next = cur; //current Node is alphabetically greater
}
}
Searching a linked list takes O(n). But since your data is sorted, putting the next string in place is a matter of finding the right location. In another data structure backed by an array, this is done by binary search and takes O(log n). See lreeder's link in the comments. Of course you can always look through the list yourself and insert the string, but that's not what a linked list is best at.

Get method in a implemented Linked List, Java

I need to implement a Linked List of integers from zero (not using existing LinkedList class).
This is the code:
A single Link class
public class Link {
public int data;
public Link nextLink;
public Link(int d1) {
data = d1;
}
public void printListElements(){
System.out.println(data);
}
}
and the LinkedList class
public class LinkedList {
private Link first;
public LinkedList(){
first = null;
}
public void add(int data1){
Link linklist = new Link(data1);
linklist.nextLink = first;
first = linklist;
}
public void printList(){
Link current=first;
System.out.println("List Elements are ");
while(current!=null){
current.printListElements();
current=current.nextLink;
}
}
}
As you see it has already add and printList method. But how do i make a get() method, which returns a value of a specific index.
This is what i mean:
public static void main(String args[]){
LinkedList MyList = new LinkedList();
MyList.add(1);
MyList.add(2);
MyList.add(3);
MyList.add(4);
System.out.println("MyList.get(0)"); // should get 1
System.out.println("MyList.get(1)"); // should get 2 etc
}
Thank You in advance.
Well, since it's a linked list, you don't have any way to directly access any element except the first one, right? So the only way to do it is to start there and step through (by successively following the links to the next element) until you reach the element specified by the index, and then return that. The easiest way to do that is with a loop.
You can't do that with your current implementation. Because you are adding every new node as the head node.
If you change your add() so that every new node is added as the last node then you can do that using your index value passed to get() as the loop counter.
In LinkedList you have your elements reverted.
public int get(int i) {
int n = indexOf(first); // count-1 actually
Link current = first;
while (n > i) {
--n;
current = current.nextLink;
}
return current.data;
}
private int indexOf(Link link) {
if (link == null) {
return -1;
}
return 1 + indexOf(link.nextLink);
}
I would recommend using a dual linked list:
class Node<T> {
Node<T> next;
Node<T> prev;
T data;
}
class LinkedList<T> {
Node<T> head;
Node<T> tail;
int count;
}
Your add method would actual just create a new node, and attach it to the "next" pointer of the tail, reassign the tail, and increment the count. (yes you could do this with a single linked list as well as long as you have a tail pointer)
Which this approach, add is a constant time operation and preserves insertion order (unlike the single linked list approach you were taking, where insertion order is not preserved).
Also, you could optimize the "get" to see if the requested index is closer to the head or tail, and traverse from the appropriate end to get the node you want.
I assume this is homework, so i don't want to give the entire code away.

Java Deque without using any of the existing classes like LinkedList?

I've got to write a very short bit of code on a deque, however I'm not sure how to write the code for the methods, if someone could help me with one of the methods, (eg. a method to add an object to the from of the deque) then that would get me started. I'm sure I could manage the rest of the methods, just at the moment I'm pretty stumped.
Deques are usually implemented as doubly linked lists. You implement a doubly linked list by keeping track of the first and last element in the list and letting each element keep track of its predecessor and successor.
public class Deque<T> {
private class Node {
Node(T value) {
this.value = value;
}
T value;
Node next, prev;
}
private Node first, last;
public void addFront(T value) {
Node oldFirst = first;
first = new Node(value);
// The old first item is now the second item, so its the successor of
// the new first item
first.next = oldFirst;
// if first was null before, that means the deque was empty
// so first and last should both point to the new item
if(oldFirst == null) {
last = first;
} else {
// If there previously was a first element, this element is
// now the second element and its prev field should point to
// the new first item
oldFirst.prev = first;
}
}
}
I'm not sure exactly what you're after, but the available methods for the Deque are listed in the Javadoc

Categories

Resources