How to use Java generics to avoid casting? - java

For the query, raised in link, Java generics is recommended to avoid difficulty in assessing run time type of an item.
After using Java generics in the below code, I do not see the incompatible type errors unlike before.
But a different compile time error at line 96 , DList1<int> l = new DList1<int>(); does not give any clue of the problem.
Error message is: Syntax error on token 'int'
/* DList1.java */
/**
* A DList1 is a mutable doubly-linked list. (No sentinel, not
* circularly linked.)
*/
public class DList1<T> {
/**
* head references the first node.
* tail references the last node.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
protected DListNode1<T> head;
protected DListNode1<T> tail;
protected long size;
/* DList1 invariants:
* 1) head.prev == null.
* 2) tail.next == null.
* 3) For any DListNode1 x in a DList, if x.next == y and x.next != null,
* then y.prev == x.
* 4) For any DListNode1 x in a DList, if x.prev == y and x.prev != null,
* then y.next == x.
* 5) The tail can be accessed from the head by a sequence of "next"
* references.
* 6) size is the number of DListNode1s that can be accessed from the
* head by a sequence of "next" references.
*/
/**
* DList1() constructor for an empty DList1.
*/
public DList1() {
this.head = null;
this.tail = null;
this.size = 0;
}
/**
* insertFront() inserts an item at the front of a DList1.
*/
public void insertFront(T item) {
if(this.head == null){
this.head = new DListNode1<T>(item);
this.tail = this.head;
}else{
DListNode1<T> newNode = new DListNode1<T>(item);
newNode.next = this.head;
this.head.prev = newNode;
this.head = newNode;
}
this.size++;
}
/**
* removeFront() removes the first item (and node) from a DList1. If the
* list is empty, do nothing.
*/
public void removeFront() {
if(this.size == 0){
return;
}else if(size ==1){
this.head = null;
this.tail = null;
}else{
this.head.next.prev = null;
this.head = this.head.next;
}
}
/**
* toString() returns a String representation of this DList.
*
* DO NOT CHANGE THIS METHOD.
*
* #return a String representation of this DList.
*/
public String toString() {
String result = "[ ";
DListNode1<T> current = head;
while (current != null) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
public static void main(String[] args) {
// DO NOT CHANGE THE FOLLOWING CODE.
DList1<int> l = new DList1<int>(); //Line 96
System.out.println("### TESTING insertFront ###\nEmpty list is " + l);
l.insertFront(9);
System.out.println("\nInserting 9 at front.\nList with 9 is " + l);
if (l.head == null) {
System.out.println("head is null.");
} else {
if (l.head.item != 9) { //Line 104
System.out.println("head.item is wrong.");
}
if (l.head.prev != null) {
System.out.println("head.prev is wrong.");
}
}
if (l.tail == null) {
System.out.println("tail is null.");
} else {
if (l.tail.item != 9) {
System.out.println("tail.item is wrong.");
}
if (l.tail.next != null) {
System.out.println("tail.next is wrong.");
}
}
if (l.size != 1) {
System.out.println("size is wrong.");
}
l.insertFront(8);
System.out.println("\nInserting 8 at front.\nList with 8 and 9 is " + l);
if (l.head == null) {
System.out.println("head is null.");
} else {
if (l.head.item != 8) {
System.out.println("head.item is wrong.");
}
if (l.head.prev != null) {
System.out.println("head.prev is wrong.");
}
if (l.head.next != l.tail) {
System.out.println("head.next is wrong.");
}
}
if (l.tail == null) {
System.out.println("tail is null.");
} else {
/*if (l.tail.item != 9) {
System.out.println("tail.item is wrong.");
}*/
if (l.tail.next != null) {
System.out.println("tail.next is wrong.");
}
if (l.tail.prev != l.head) {
System.out.println("tail.prev is wrong.");
}
}
if (l.size != 2) {
System.out.println("size is wrong.");
}
} /* end main() */
}
/* DListNode1.java */
/**
* A DListNode1 is a node in a DList1 (doubly-linked list).
*/
class DListNode1<T> {
/**
* item references the item stored in the current node.
* prev references the previous node in the DList.
* next references the next node in the DList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
T item;
DListNode1<T> prev;
DListNode1<T> next;
/**
* DListNode1() constructor.
*/
DListNode1() {
this.item = null;
this.prev = null;
this.next = null;
}
DListNode1(T item) {
this.item = item;
this.prev = null;
this.next = null;
}
}
My question:
What is the meaning of this error at Line 96? How do i resolve this?
Note: using jre 1.6 update 45

In Java you can't parametrize a type with primitive values like int, so instead of:
DList1<int> l = new DList1<int>();
use wrapper classes:
DList1<Integer> l = new DList1<Integer>();

Related

swap two nodes in singly linked lists using method in java

package linkedlists;
public class SinglyLinkedList<E> implements Cloneable {
//---------------- nested Node class ----------------
/**
* Node of a singly linked list, which stores a reference to its
* element and to the subsequent node in the list (or null if this
* is the last node).
*/
private static class Node<E> {
/** The element stored at this node */
private E element; // reference to the element stored at this node
/** A reference to the subsequent node in the list */
private Node<E> next; // reference to the subsequent node in the list
/**
* Creates a node with the given element and next node.
*
* #param e the element to be stored
* #param n reference to a node that should follow the new node
*/
public Node(E e, Node<E> n) {
element = e;
next = n;
}
// Accessor methods
/**
* Returns the element stored at the node.
* #return the element stored at the node
*/
public E getElement() { return element; }
/**
* Returns the node that follows this one (or null if no such node).
* #return the following node
*/
public Node<E> getNext() { return next; }
// Modifier methods
/**
* Sets the node's next reference to point to Node n.
* #param n the node that should follow this one
*/
public void setNext(Node<E> n) { next = n; }
} //----------- end of nested Node class -----------
// instance variables of the SinglyLinkedList
/** The head node of the list */
private Node<E> head = null; // head node of the list (or null if empty)
/** The last node of the list */
private Node<E> tail = null; // last node of the list (or null if empty)
/** Number of nodes in the list */
private int size = 0; // number of nodes in the list
/** Constructs an initially empty list. */
public SinglyLinkedList() { } // constructs an initially empty list
// access methods
/**
* Returns the number of elements in the linked list.
* #return number of elements in the linked list
*/
public int size() { return size; }
/**
* Tests whether the linked list is empty.
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() { return size == 0; }
/**
* Returns (but does not remove) the first element of the list
* #return element at the front of the list (or null if empty)
*/
public E first() { // returns (but does not remove) the first element
if (isEmpty()) return null;
return head.getElement();
}
/**
* Returns (but does not remove) the last element of the list.
* #return element at the end of the list (or null if empty)
*/
public E last() { // returns (but does not remove) the last element
if (isEmpty()) return null;
return tail.getElement();
}
// update methods
/**
* Adds an element to the front of the list.
* #param e the new element to add
*/
public void addFirst(E e) { // adds element e to the front of the list
head = new Node<>(e, head); // create and link a new node
if (size == 0)
tail = head; // special case: new node becomes tail also
size++;
}
/**
* Adds an element to the end of the list.
* #param e the new element to add
*/
public void addLast(E e) { // adds element e to the end of the list
Node<E> newest = new Node<>(e, null); // node will eventually be the tail
if (isEmpty())
head = newest; // special case: previously empty list
else
tail.setNext(newest); // new node after existing tail
tail = newest; // new node becomes the tail
size++;
}
/**
* Removes and returns the first element of the list.
* #return the removed element (or null if empty)
*/
public E removeFirst() { // removes and returns the first element
if (isEmpty()) return null; // nothing to remove
E answer = head.getElement();
head = head.getNext(); // will become null if list had only one node
size--;
if (size == 0)
tail = null; // special case as list is now empty
return answer;
}
#SuppressWarnings({"unchecked"})
public boolean equals(Object o) {
if (o == null) return false;
if (getClass() != o.getClass()) return false;
SinglyLinkedList other = (SinglyLinkedList) o; // use nonparameterized type
if (size != other.size) return false;
Node walkA = head; // traverse the primary list
Node walkB = other.head; // traverse the secondary list
while (walkA != null) {
if (!walkA.getElement().equals(walkB.getElement())) return false; //mismatch
walkA = walkA.getNext();
walkB = walkB.getNext();
}
return true; // if we reach this, everything matched successfully
}
#SuppressWarnings({"unchecked"})
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
// always use inherited Object.clone() to create the initial copy
SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone(); // safe cast
if (size > 0) { // we need independent chain of nodes
other.head = new Node<>(head.getElement(), null);
Node<E> walk = head.getNext(); // walk through remainder of original list
Node<E> otherTail = other.head; // remember most recently created node
while (walk != null) { // make a new node storing same element
Node<E> newest = new Node<>(walk.getElement(), null);
otherTail.setNext(newest); // link previous node to this one
otherTail = newest;
walk = walk.getNext();
}
}
return other;
}
public int hashCode() {
int h = 0;
for (Node walk=head; walk != null; walk = walk.getNext()) {
h ^= walk.getElement().hashCode(); // bitwise exclusive-or with element's code
h = (h << 5) | (h >>> 27); // 5-bit cyclic shift of composite code
}
return h;
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
*/
public String toString() {
StringBuilder sb = new StringBuilder("(");
Node<E> walk = head;
while (walk != null) {
sb.append(walk.getElement());
if (walk != tail)
sb.append(", ");
walk = walk.getNext();
}
sb.append(")");
return sb.toString();
}
public void swapNodes(Node<E> num1, Node<E> num2) {
Node<E> num1Prev = this.head;
Node<E> num2Prev = this.head;
if (num1 == num2 )
return ;
while((num1Prev != null)&&(num1Prev.getNext() != num1)){
num1Prev = num1Prev.getNext();
}
while((num2Prev != null)&&(num2Prev.getNext() != num2)){
num2Prev = num2Prev.getNext();
}
if(num2Prev == num1) {
num1.setNext(num2.getNext());
num2.setNext(num1);
num1Prev.setNext(num2);
}
else if(num1Prev == num2) {
num2.setNext(num1.getNext());
num1.setNext(num2);
num2Prev.setNext(num1);
}
else {
Node<E> tmp = num1.getNext();
num1.setNext(num2.getNext());
num2.setNext(tmp);
num1Prev.setNext(num2);
num2Prev.setNext(num1);
}
}
//main method
public static void main(String[] args)
{
SinglyLinkedList<String> list = new SinglyLinkedList<String>();
list.addFirst("MSP");
list.addLast("ATL");
list.addLast("BOS");
//
list.addFirst("LAX");
System.out.println(list);
//
SinglyLinkedList<String> swap = new SinglyLinkedList<String>();
swap.addFirst("1");
swap.addLast("2");
swap.addLast("3");
swap.addLast("4");
swap.addLast("5");
System.out.println("Original list: " + swap);
swap.swapNodes("2","5");
System.out.println("After Swapping list: " + swap);
}
}
Task: In this exercise, you will add a method swapNodes to SinglyLinkedList class from week 2 lecture examples. This method should swap two nodes node1 and node2 (and not just their contents) given references only to node1 and node2. The new method should check if node1 and node2 are the same nodes, etc. Write the main method to test the swapNodes method. Hint: You may need to traverse the list.
I made this method
public void swapNodes(Node<E> num1, Node<E> num2) {
Node<E> num1Prev = this.head;
Node<E> num2Prev = this.head;
if (num1 == num2 )
return ;
while((num1Prev != null)&&(num1Prev.getNext() != num1)){
num1Prev = num1Prev.getNext();
}
while((num2Prev != null)&&(num2Prev.getNext() != num2)){
num2Prev = num2Prev.getNext();
}
if(num2Prev == num1) {
num1.setNext(num2.getNext());
num2.setNext(num1);
num1Prev.setNext(num2);
}
else if(num1Prev == num2) {
num2.setNext(num1.getNext());
num1.setNext(num2);
num2Prev.setNext(num1);
}
else {
Node<E> tmp = num1.getNext();
num1.setNext(num2.getNext());
num2.setNext(tmp);
num1Prev.setNext(num2);
num2Prev.setNext(num1);
}
}
And then, created an instance to check if it's work, but it is showing me an error on here swap.swapNodes("2", "5");
Does anyone know what is the problem? Thank you
It's throwing error, because in your swapNodes function, you expect two parameters of type Node<E> passed, but you are passing E (String). So you have to change signature of the function or pass Node<E> that you added to your List.
Here's how you could do your swapNodes function with parameters of type E:
public void swapNodes(E element1, E element2) {
if (element1 == element2 || element1 == null || element2 == null || isEmpty()) return;
Node<E> num1 = findNode(element1);
Node<E> num2 = findNode(element2);
if (num1 == null || num2 == null) return;
Node<E> num1Prev = this.head;
Node<E> num2Prev = this.head;
while(num1Prev != null && num1Prev.getNext() != num1){
num1Prev = num1Prev.getNext();
}
while(num2Prev != null && num2Prev.getNext() != num2){
num2Prev = num2Prev.getNext();
}
if (num1Prev.getNext() == null || num2Prev.getNext() == null) return;
if (num2Prev.equals(num1)) {
num1.setNext(num2.getNext());
num2.setNext(num1);
num1Prev.setNext(num2;
} else if (num1Prev.equals(num2)) {
num2.setNext(num1.getNext());
num1.setNext(num2);
num2Prev.setNext(num1);
} else {
Node<E> tmp = num1.getNext();
num1.setNext(num2.getNext());
num2.setNext(tmp);
num1Prev.setNext(num2);
num2Prev.setNext(num1);
}
}
The findNode function could look like this:
public Node<E> findNode(E element) {
if (isEmpty()) return null;
Node<E> node = this.head;
while(node != null) {
if (node.getElement() == element) return node;
}
return null;
}

I have stuck with making remove()

Hi I'm trying to make remove method. But I don't know How to make this right. Here is my code.
This is LinkedList.java from Algorithm fourth edition.
/**
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin
* Wayne.
* #author Robert Sedgewick
* #author Kevin Wayne
*/
public class LinkedQueue<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty queue.
*/
public LinkedQueue() {
first = null;
last = null;
N = 0;
assert check();
}
/**
* Is this queue empty?
* #return true if this queue is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns the number of items in this queue.
* #return the number of items in this queue
*/
public int size() {
return N;
}
/**
* Returns the item least recently added to this queue.
* #return the item least recently added to this queue
* #throws java.util.NoSuchElementException if this queue is empty
*/
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
return first.item;
}
/**
* Adds the item to this queue.
* #param item the item to add
*/
public void enqueue(Item item) {
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
N++;
assert check();
}
/**
* Removes and returns the item on this queue that was least recently added.
* #return the item on this queue that was least recently added
* #throws java.util.NoSuchElementException if this queue is empty
*/
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
assert check();
return item;
}
/**
* Returns a string representation of this queue.
* #return the sequence of items in FIFO order, separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
// check internal invariants
private boolean check() {
if (N == 0) {
if (first != null) return false;
if (last != null) return false;
}
else if (N == 1) {
if (first == null || last == null) return false;
if (first != last) return false;
if (first.next != null) return false;
}
else {
if (first == last) return false;
if (first.next == null) return false;
if (last.next != null) return false;
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
// check internal consistency of instance variable last
Node lastNode = first;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
if (last != lastNode) return false;
}
return true;
}
//working properly
void reverseBystack(){
Stack<Item> s = new Stack<>();
Item item;
while (isEmpty() != true){
item = dequeue();
s.push(item);
}
while(s.isEmpty() != true){
item = s.pop();
enqueue(item);
}
}
//working properly.
void reverseBylink() {
Node prev = null;
Node current = this.first;
Node next = null;
Node temp = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
temp =first;
first = last;
last = temp;
}
//How to do this...;<..
int remove(Item item) {
Node cur = this.first;
while (cur !=null) {
if (cur.item.equals(item)) {
item = dequeue();
}
cur = cur.next;
N++;
}
return 0;
}
/**
* Returns an iterator that iterates over the items in this queue in FIFO order.
* #return an iterator that iterates over the items in this queue in FIFO order
*/
public Iterator<Item> iterator() {
return new ListIterator();
}
// an iterator, doesn't implement remove() since it's optional
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
Unit tests
/**
* Unit tests the <tt>LinkedQueue</tt> data type.
*/
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
/* Working properly for reverseByStack.
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
q.reverseBystack();
System.out.println(q);
StdOut.println("(" + q.size() + " left on queue)");
*/
/*Move on to next, working properly
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
q.reverseBylink();
System.out.println(q);
StdOut.println("(" + q.size() + "left on queue)");*/
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
System.out.println(q);
System.out.println("Remove some of elements. and use reverseByLink");
q.remove("a");
q.remove("f");
q.remove("c");
System.out.println(q);
}
Output.
a b c a b d b abba a z a
Remove some of elements. and use reverseByLink
a b d b abba a z a
I don't know why String a is not removed and after abba.
int remove(Item item) {
if(this.first == null)
return 0;
if(this.first == item) {
// remove root item
Node node = this.first.next;
this.first.next = null;
this.first = node;
return 1;
}
Node prv = this.first;
while (prv.next != item)
prv = prv.next;
// item was not found
if(prv == null)
return 0;
Node node = prv.next.next;
prv.next.next = null;
prv.next = node;
return 1;
}
I'm fairly sure this method is wrong:
int remove(Item item) {
Node cur = this.first;
while (cur !=null) {
if (cur.item.equals(item)) {
item = dequeue();
}
cur = cur.next;
N++;
}
return 0;
}
Your dequeue method pops the front of the list. But the item you're removing might not be the front of the list.
I didn't look for more problems.
This is standard linked list stuff. Some of your textbooks should have algorithms for this. But basically, you need to keep track of the last pointer you used. Let's say you have lastPtr and currentPtr, and you determine that currentPtr needs to go.
Then lastPtr.next = currentPtr.next
It's more interesting if you're at the head. You need to recognize that and instead do first.next = currentPtr.next.
dequeue() methods is popping out items from the front , but to remove all the occurrences of any string , you need to modify your remove() method to -
void remove(Item item) {
Node cur = this.first;
Node prev = null;
if(this.first.item.equals(item)){
item = dequeue();
cur = this.first;
}
while (cur != null) {
/* if (cur.item.equals(item)) {
item = dequeue();
}*/
while(cur != null && !cur.item.equals(item)) {
prev = cur;
cur = cur.next;
}
if(cur == null)
return;
prev.next = cur.next;
cur = prev.next;
}
return ;
}

Apending to Linked List in Java

The code compiles and runs but addToEnd method doesn't work, it seems right to me but I'm not sure where the mistake is, could someone guide me as to what or where the code needs to be fixed
Here is the code for my other class
public class LinkedList {
private Node head;
/**
* constructor
* pre: none
* post: A linked list with a null item has been created.
*/
public LinkedList() {
head = null;
}
/**
* Activity: finds size of the Linked List.
* Pre-Condition: none
* Post-Condition: The size of the list is returned
*/
public int size() {
int counter = 0;
Node current = head;
while(current != null) {
counter++;
current = current.getNext();
}
return counter;
}
/**
* Adds a node to the end of the linked list.
* pre: String parameter
* post: The linked list has a new node at the end.
*/
public void addAtEnd(String s) {
Node current = head;
Node newNode = new Node(s);
if(head == null) {
head = newNode;
head.setNext(null);
}
else {
while(current.getNext() == null) {
current.setNext(newNode);
current = newNode;
}
}
}
private class Node {
private String data;
private Node next;
/**
* constructor
* pre: none
* post: A node has been created.
*/
public Node(String newData) {
data = newData;
next = null;
}
/**
* The node pointed to by next is returned
* pre: none
* post: A node has been returned.
*/
public Node getNext() {
return(next);
}
/**
* The node pointed to by next is changed to newNode
* pre: none
* post: next points to newNode.
*/
public void setNext(Node newNode) {
next = newNode;
}
/**
* The node pointed to by next is returned
* pre: none
* post: A node has been returned.
*/
public String getData() {
return(data);
}
}
}
Here is my code for the main class, Blume and Dahl never get added to the list:
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addAtFront("Sachar");
list.addAtFront("Osborne");
list.addAtFront("Suess");
System.out.println("List has " + list.size() + " items.");
System.out.println(list);
list.addAtEnd("Blume");
list.addAtEnd("Dahl");
System.out.println(list);
}
}
public void addAtEnd(String s) {
Node current = head;
Node newNode = new Node(s);
if(head == null) {
head = newNode;
head.setNext(null);
}
else {// problem is here. You need to find the node that has getNext()==null,
//so you need to loop all nodes where get next != null
while(current.getNext() == null) {
current.setNext(newNode);
current = newNode;
}
}
Change to this
else{
//iterate to the last node
while(current.getNext() != null) {
current = current.getNext();
}
//Append the new node to the end
current.setNext(newNode);
}
while (current.getNext() == null) {
current.setNext(newNode);
current = newNode;
}
This is just incorrect; because you're not keeping track of the tail of the list, you need to iterate over the entire list and then add newNode onto the end (which I believe you understand already). To do this, just keep setting current to current.getNext() until current.getNext() is null, and then call current.setNext(newNode);
Node next;
while ((next = current.getNext()) != null) {
current = next;
}
current.setNext(newNode);
public void addAtEnd(String s) {
Node current = head;
Node newNode = new Node(s);
if(current == null) {
head = newNode;
} else {
while(current.getNext() != null) {
current = current.getNext();
}
current.setNext(newNode);
}
}

Where should I put "public static void main(String[] args)" in this program?

I have a program that is supposed to allow me to create an RB Tree, but when I run it, I get the following error:
run:
Error: Main method not found in class mainrbt.MainRBT, please define the main method as:
public static void main(String[] args)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
I've been trying to figure out if I can just put the "public static void main(String[] args)" somewhere inside so that I can go ahead and run it, but so far I have been unsuccessful.
Here is the MainRBT.java:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mainrbt;
import java.util.Random;
import java.util.Stack;
public class MainRBT {
/* *************************************************** *
* PRIVATE FIELDS *
* *************************************************** */
private RBTree tree;
private int size;
/* If during an insert() or delete() it is found that
* the key is present in the tree, keyFound will be true
* and prevValue will contain the previous value
* associated with the key before the update.
*/
private boolean keyFound;
private Object prevValue;
/* *************************************************** *
* PUBLIC INTERFACE *
* *************************************************** */
/*
* Constructs a new empty red-black tree.
*/
public MainRBT() {
tree = null;
size = 0;
}
/**
* Maps the key to the specified value in this red-black tree.
* Neither the key, nor the value can be
* <code>null</code>.
* #return the previous value to which the key was mapped,
* or <code>null</code> if the key did not have a previous
* mapping in the red-black tree.
*/
public synchronized Object put(/*Si*/String key, Object value) {
if (key == null || value == null)
throw new NullPointerException();
RBTree node = new RBTree();
node.key = key;
node.value = value;
keyFound = false;
tree = insert(node, tree);
if (keyFound)
return prevValue;
else {
size++;
return null;
}
}
/**
* Gets the object associated with the specified key in the red-black tree.
* #param args
* #return the value to which the key is mapped in the red-black tree, or
* <code>null</code> if the key is not mapped to any value in
* this red-black tree.
*/
public synchronized Object get(/*Si*/String key) {
RBTree t = tree;
int comp;
while (t != null && (comp = key.compareTo(t.key)) != 0)
if (comp < 0)
t = t.left;
else
t = t.right;
return t != null ? t.value : null;
}
/**
* Returns <code>true</code> if this red-black tree contains no mappings.
*/
public boolean isEmpty() {
return tree == null;
}
/**
* Removes the key (and its corresponding value) from this red-black tree.
* This method does nothing if the key is not in the red-black tree.
* #return the value to which the key had been mapped in this red-black tree,
* or <code>null</code> if the key did not have a mapping.
*/
public synchronized Object remove(/*Si*/String key) {
RBTree node = tree;
while (node != null) {
int comp = key.compareTo(node.key);
if (comp < 0)
node = node.left;
else if (comp > 0)
node = node.right;
else {
prevValue = node.value;
tree = delete(node, tree);
size--;
return prevValue;
}
}
return null;
}
/**
* Clear the red-black tree so that it contains no mappings.
*/
public synchronized void clear() {
tree = null;
size = 0;
}
/**
* Returns the number of keys in this red-black tree.
*/
public int size() {
return size;
}
/**
* Returns a string representation of this red-black tree.
* This routine is inefficient and primarily intended for
* debugging. To access the elements in the red-black tree in sorted order
* use the <code>keys()</code> and <code>elements()</code> methods.
* #see RedBlackTree#keys
* #see RedBlackTree#elements
*/
public synchronized String toString() {
StringBuffer strbuf = new StringBuffer();
strbuf.append("{");
if (tree != null)
strbuf.append(tree.toString());
if (strbuf.length() > 1)
strbuf.setLength(strbuf.length() - 2); // remove last ", "
strbuf.append("}");
return strbuf.toString();
}
/**
* Returns a string displaying the tree structure
* and the priority numbers.
*/
public synchronized String printDebug() {
StringBuffer strbuf = new StringBuffer();
String newline = System.getProperty("line.separator");
strbuf.append("size: " + size + newline);
if (tree != null)
tree.printDebug(0, strbuf);
return strbuf.toString();
}
public String printStat() {
StatStruct stat = new StatStruct();
collectStat(tree, 0, stat);
StringBuffer strbuf = new StringBuffer();
String newline = System.getProperty("line.separator");
strbuf.append("Aver depth: " +
(float) stat.totDepth / this.size + newline);
strbuf.append("Max depth: " + stat.maxDepth + newline);
return strbuf.toString();
}
/* *************************************************** *
* PRIVATE METHODS *
* *************************************************** */
/* Inserts a node into tree and returns the updated red-black tree */
private RBTree insert(RBTree node, RBTree tree) {
RBTree father = null, son = tree;
/* Insert the new node into the tree. */
while (son != null) {
father = son;
int comp = node.key.compareTo(son.key);
if (comp < 0)
son = son.left;
else if (comp > 0)
son = son.right;
else {
keyFound = true;
prevValue = son.value;
son.value = node.value;
return tree;
}
}
node.parent = father;
if (father == null)
tree = node;
else if (node.key.compareTo(father.key) < 0)
father.left = node;
else father.right = node;
/* Inforce the color invariants of the red-black tree. */
node.color = RBTree.RED;
while (node != tree && node.parent.color == RBTree.RED) {
if (node.parent == node.parent.parent.left) {
son = node.parent.parent.right;
if (son != null && son.color == RBTree.RED) {
node.parent.color = RBTree.BLACK;
son.color = RBTree.BLACK;
node = node.parent.parent;
node.color = RBTree.RED;
} else {
if (node == node.parent.right) {
node = node.parent;
tree = node.rotateLeft(tree);
}
node.parent.color = RBTree.BLACK;
node.parent.parent.color = RBTree.RED;
tree = node.parent.parent.rotateRight(tree);
}
} else {
son = node.parent.parent.left;
if (son != null && son.color == RBTree.RED) {
node.parent.color = RBTree.BLACK;
son.color = RBTree.BLACK;
node = node.parent.parent;
node.color = RBTree.RED;
} else {
if (node == node.parent.left) {
node = node.parent;
tree = node.rotateRight(tree);
}
node.parent.color = RBTree.BLACK;
node.parent.parent.color = RBTree.RED;
tree = node.parent.parent.rotateLeft(tree);
}
}
}
tree.color = RBTree.BLACK;
return tree;
}
/* Deletes a node from a red-black tree and
* returns the updated red-black tree.
*/
private RBTree delete(RBTree node, RBTree tree) {
RBTree x, y;
if (node.left == null || node.right == null)
y = node;
else
y = node.successorGet();
if (y.left != null)
x = y.left;
else
x = y.right;
if (x != null)
x.parent = y.parent;
if (y.parent == null)
tree = x;
else if (y == y.parent.left)
y.parent.left = x;
else
y.parent.right = x;
if (y != node) {
node.key = y.key;
node.value = y.value;
}
/* If the node to be removed is BLACK,
* restore the red-black tree invariants.
* The color of a null leaf is BLACK.
*/
if (y.color == RBTree.BLACK) {
RBTree father = y.parent;
while (x != tree && (x == null || x.color == RBTree.BLACK)) {
if (x == father.left) {
RBTree w = father.right;
if (w == null)
x = tree;
else {
if (w.color == RBTree.RED) {
w.color = RBTree.BLACK;
father.color = RBTree.RED;
tree = father.rotateLeft(tree);
continue;
}
if ((w.left == null || w.left.color == RBTree.BLACK) &&
(w.right == null || w.right.color == RBTree.BLACK)) {
w.color = RBTree.RED;
x = father;
father = x.parent;
}
else {
if (w.right == null || w.right.color == RBTree.BLACK) {
if (w.left != null) {
w.left.color = RBTree.BLACK;
w.color = RBTree.RED;
tree = w.rotateRight(tree);
w = father.right;
}
}
w.color = father.color;
father.color = RBTree.BLACK;
if (w.right != null)
w.right.color = RBTree.BLACK;
tree = father.rotateLeft(tree);
x = tree;
}
}
} else {
RBTree w = father.left;
if (w == null)
x = tree;
else {
if (w.color == RBTree.RED) {
w.color = RBTree.BLACK;
father.color = RBTree.RED;
tree = father.rotateRight(tree);
continue;
}
if ((w.right == null || w.right.color == RBTree.BLACK) &&
(w.left == null || w.left.color == RBTree.BLACK)) {
w.color = RBTree.RED;
x = father;
father = x.parent;
}
else {
if (w.left == null || w.left.color == RBTree.BLACK) {
if (w.right != null) {
w.right.color = RBTree.BLACK;
w.color = RBTree.RED;
tree = w.rotateLeft(tree);
w = father.left;
}
}
w.color = father.color;
father.color = RBTree.BLACK;
if (w.left != null)
w.left.color = RBTree.BLACK;
tree = father.rotateRight(tree);
x = tree;
}
}
}
}
if (x != null)
x.color = RBTree.BLACK;
}
return tree;
}
private class StatStruct {
int totDepth = 0;
int maxDepth = 0;
}
private void collectStat(RBTree t, int depth, StatStruct stat) {
if (t == null)
return;
else {
if (depth > stat.maxDepth)
stat.maxDepth = depth;
stat.totDepth += depth;
collectStat(t.left, depth + 1, stat);
collectStat(t.right, depth + 1, stat);
}
}
}
In addition, here is my RBTree.java file, in case it is also relevant to this problem:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mainrbt;
/**
*
* #author Owner
*/
public class RBTree {
public static final short BLACK = 0;
public static final short RED = 1;
short color;
RBTree left, right, parent;
/*Si*/String key;
Object value;
/* Rotate this tree to the left, update parent,
* and return the root.
*/
final RBTree rotateLeft(RBTree root) {
RBTree temp = right;
right = temp.left;
if (temp.left != null)
temp.left.parent = this;
temp.parent = parent;
if (parent == null)
root = temp;
else
if (this == parent.left)
parent.left = temp;
else
parent.right = temp;
temp.left = this;
parent = temp;
return root;
}
/* Rotate this tree to the right, update parent,
* and return the root.
*/
final RBTree rotateRight(RBTree root) {
RBTree temp = left;
left = temp.right;
if (temp.right != null)
temp.right.parent = this;
temp.parent = parent;
if (parent == null)
root = temp;
else
if (this == parent.right)
parent.right = temp;
else
parent.left = temp;
temp.right = this;
parent = temp;
return root;
}
/* Get the successor of this tree.
*/
final RBTree successorGet() {
RBTree temp, p;
if (right != null) {
temp = right;
while (temp.left != null)
temp = temp.left;
}
else {
temp = this;
p = parent;
while (p != null && temp == p.right) {
temp = p;
p = p.parent;
}
}
return temp;
}
public String toString() {
StringBuffer strbuf = new StringBuffer();
if (left != null)
strbuf.append(left.toString());
strbuf.append(key + "=" + value + ", ");
if (right != null)
strbuf.append(right.toString());
return strbuf.toString();
}
/* Print in sorted order, displaying the tree structure
* and the node colors.
*/
void printDebug(int level, StringBuffer strbuf) {
String newline = System.getProperty("line.separator");
if (left != null)
left.printDebug(level + 1, strbuf);
for (int i = 0; i < level; i++)
strbuf.append(" ");
if (color == RBTree.BLACK)
strbuf.append("BLACK, " + value + ": " + key + newline);
else
strbuf.append("RED, " + value + ": " + key + newline);
if (right != null)
right.printDebug(level + 1, strbuf);
}
}
If anyone knows how to fix this error, please let me know.
Which ever class needs to run first is the one you put that method in.
Put main method into the class which you want to run your codes first. Main method just like a entrance of your project.

Sorted Linked List using comparable in Java

I am writing a ordered linked list for an assignment. We are using comparable, and I am struggling to get boolean add to work properly. I have labored over this code for two weeks now, and I am going cross-eyed looking at the code. I could really appreciate a fresh set of eyes on my code.
The code should work for Comparable data - both ints and String (not mixed though). I can get close to making each work, but not one code that stands for all. Please help me fix this, so the code works for either Strings or Ints.
I am only allowed to alter the add(), remove() and OrderedListNode classes
Update Thanks to parkydr, I was able to work out some of my issues, however, I am still getting a null point error. I am testing both int and Strings. If the String loop has a "<" in the while section then elements come back in reverse order. I will be an error for ints with that though. If I have >=, like parkydr said, then I get back the ints in proper order, but Strings get a null pointer error. How do I get both to work together?
Update2 the ints need to be in order, like in the code from AmitG.
Edit Does anyone have any ideas?
package dataStructures;
/**
* Class OrderedLinkedList.
*
* This class functions as a linked list, but ensures items are stored in ascending
order.
*
*/
public class OrderedLinkedList
{
/**************************************************************************
* Constants
*************************************************************************/
/** return value for unsuccessful searches */
private static final OrderedListNode NOT_FOUND = null;
/**************************************************************************
* Attributes
*************************************************************************/
/** current number of items in list */
private int theSize;
/** reference to list header node */
private OrderedListNode head;
/** reference to list tail node */
private OrderedListNode tail;
/** current number of modifications to list */
private int modCount;
/**************************************************************************
* Constructors
*************************************************************************/
/**
* Create an instance of OrderedLinkedList.
*
*/
public OrderedLinkedList()
{
// empty this OrderedLinkedList
clear();
}
/**************************************************************************
* Methods
*************************************************************************/
/*
* Add the specified item to this OrderedLinkedList.
*
* #param obj the item to be added
*/
public boolean add(Comparable obj){
OrderedListNode node = new OrderedListNode(obj);
OrderedListNode head2 = new OrderedListNode(obj);
OrderedListNode tail2 = new OrderedListNode(obj);
if (head2 == null)
{
head2 = node;
tail2 = node;
return true;
}
// When the element to be added is less than the first element in the list
if (obj.compareTo(head2.theItem) < 0)
{
node.next = head2;
head2 = node;
return true;
}
// When the element to be added is greater than every element in in list
// and has to be added at end of the list
if (obj.compareTo(tail2.theItem) > 0)
{
tail2.next = node;
tail2 = node;
return true;
}
//When the element to be added lies between other elements in the list
if (obj.compareTo(head2.theItem) >= 0 && obj.compareTo(tail2.theItem) <= 0)
{
OrderedListNode current = head.next;
OrderedListNode previous = head;
while (obj.compareTo(current.theItem) >= 0)
{
previous = current;
current = current.next;
}
previous.next = node;
node.next = current;
}
return true;
}
/*
* Remove the first occurrence of the specified item from this
OrderedLinkedList.
*
* #param obj the item to be removed
*/
public boolean remove(Comparable obj)
{
OrderedListNode curr = head;
OrderedListNode prev = head;
while(curr != null && ! (curr.theItem.compareTo(obj) == 0)){
prev = curr;
curr = curr.next;
}
if(curr == null)
return false;
else{
prev.next = curr.next;
curr = null;
return true;
}
}
/**
* Empty this OrderedLinkedList.
*/
public void clear()
{
// reset header node
head = new OrderedListNode("HEAD", null, null);
// reset tail node
tail = new OrderedListNode("TAIL", head, null);
// header references tail in an empty LinkedList
head.next = tail;
// reset size to 0
theSize = 0;
// emptying list counts as a modification
modCount++;
}
/**
* Return true if this OrderedLinkedList contains 0 items.
*/
public boolean isEmpty()
{
return theSize == 0;
}
/**
* Return the number of items in this OrderedLinkedList.
*/
public int size()
{
return theSize;
}
/*
* Return a String representation of this OrderedLinkedList.
*
* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString()
{
String s = "";
OrderedListNode currentNode = head.next;
while (currentNode != tail)
{
s += currentNode.theItem.toString();
if (currentNode.next != tail)
{
s += ", ";
}
currentNode = currentNode.next;
}
return s;
}
/**************************************************************************
* Inner Classes
*************************************************************************/
/**
* Nested class OrderedListNode.
*
* Encapsulates the fundamental building block of an OrderedLinkedList
* contains a data item, and references to both the next and previous nodes
* in the list
*/
// TODO: Implement the nested class OrderedListNode (5 points). This nested class
// should be similar to the nested class ListNode of the class LinkedList, but
// should store a data item of type Comparable rather than Object.
public static class OrderedListNode {
Comparable theItem;
OrderedListNode next;
OrderedListNode prev;
OrderedListNode( Comparable theItem ) { this( theItem, null, null ); }
OrderedListNode( Comparable theItem, OrderedListNode prev, OrderedListNode next)
{
this.theItem = theItem;
this.next = next;
this.prev = prev;
}
Comparable getData() { return theItem; }
OrderedListNode getNext() { return next; }
OrderedListNode getPrev() { return prev; }
}
// Remove - for testing only
public static void main (String[] args)
{
OrderedLinkedList list = new OrderedLinkedList();
list.add("1");
list.add("4");
list.add("3");
list.add("33");
list.add("4");
System.out.println(list.toString());
}
}
This above code works for ints for the most part except that items are stored as strings lexically. So I need help fixing that. I also need to make this code work with Strings as well. Right now the below code works with String but not ints, it also stores in reverse order since the <= changes in the while statement. Help!
Notice that the change in sign will make Strings work (albeit in reverse order):
while (obj.compareTo(current.theItem) <= 0)
Here's my latest version of add. It does not set up the prev links (I'll leave that as an "exercise for the reader").
public boolean add(Comparable obj){
OrderedListNode node = new OrderedListNode(obj);
// When the list is empty
if (head.next == tail)
{
head.next = node;
node.next = tail;
tail.prev = node;
return true;
}
// When the element to be added is less than the first element in the list
if (obj.compareTo(head.next.theItem) < 0)
{
node.next = head.next;
head.next = node;
return true;
}
//When there is an element in the list
OrderedListNode current = head.next;
OrderedListNode previous = head;
while (current != tail && node.theItem.compareTo(current.theItem) >= 0)
{
previous = current;
current = current.next;
}
previous.next = node;
node.next = current;
return true;
}
Modified program, output will be 1,3,33,4,4
if you want output like 1,3,4,4,33 then remove line 1 and line 2 from the following program and paste following code. Add and toString methods are modified.
int currentValue = Integer.parseInt(freshNode.theItem.toString());
int tempValue = Integer.parseInt(nodeToTraverse.theItem.toString());
if(currentValue>tempValue)
Complete code
/**
* Class OrderedLinkedList.
*
* This class functions as a linked list, but ensures items are stored in
* ascending order.
*
*/
public class OrderedLinkedList {
/**************************************************************************
* Constants
*************************************************************************/
/** return value for unsuccessful searches */
private static final OrderedListNode NOT_FOUND = null;
/**************************************************************************
* Attributes
*************************************************************************/
/** current number of items in list */
private int theSize;
/** reference to list header node */
private OrderedListNode head;
/** reference to list tail node */
private OrderedListNode tail;
/** current number of modifications to list */
private int modCount;
/**************************************************************************
* Constructors
*************************************************************************/
/**
* Create an instance of OrderedLinkedList.
*
*/
public OrderedLinkedList() {
// empty this OrderedLinkedList
// clear(); //work around with this method. Removed temporarily.
}
/**************************************************************************
* Methods
*************************************************************************/
/*
* Add the specified item to this OrderedLinkedList.
*
* #param obj the item to be added
*/
public void add(Comparable obj) {
OrderedListNode freshNode = new OrderedListNode(obj);
if (head == null) {
head = freshNode;
tail = freshNode;
return;
}
OrderedListNode nodeToTraverse = head;
while(nodeToTraverse!=null)
{
int result = freshNode.theItem.compareTo(nodeToTraverse.theItem); // line 1
if(result>0) // line 2
{
if(nodeToTraverse.next==null)
{
nodeToTraverse.next=freshNode;
freshNode.prev =nodeToTraverse;
break;
}
else
{
nodeToTraverse=nodeToTraverse.next;
continue;
}
}
else
{
nodeToTraverse.prev.next = freshNode;
freshNode.prev = nodeToTraverse.prev;
freshNode.next= nodeToTraverse;
nodeToTraverse.prev=freshNode;
break;
}
}
}
/*
* Remove the first occurrence of the specified item from this
* OrderedLinkedList.
*
* #param obj the item to be removed
*/
public boolean remove(Comparable obj) {
OrderedListNode curr = head;
OrderedListNode prev = head;
while (curr != null && !(curr.theItem.compareTo(obj) == 0)) {
prev = curr;
curr = curr.next;
}
if (curr == null)
return false;
else {
prev.next = curr.next;
curr = null;
return true;
}
}
/**
* Empty this OrderedLinkedList.
*/
public void clear() {
// reset header node
head = new OrderedListNode("HEAD", null, null);
// reset tail node
tail = new OrderedListNode("TAIL", head, null);
// header references tail in an empty LinkedList
head.next = tail;
// reset size to 0
theSize = 0;
// emptying list counts as a modification
modCount++;
}
/**
* Return true if this OrderedLinkedList contains 0 items.
*/
public boolean isEmpty() {
return theSize == 0;
}
/**
* Return the number of items in this OrderedLinkedList.
*/
public int size() {
return theSize;
}
/*
* Return a String representation of this OrderedLinkedList.
*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
String s = "";
OrderedListNode temp = head;
while (temp != null) {
s = s + temp.theItem.toString()+",";
temp = temp.next;
}
return s.substring(0,s.lastIndexOf(",")); //this will remove last comma
// return s; //1,2,3,4,5,25,33, this will not remove last comma(,)
}
/**************************************************************************
* Inner Classes
*************************************************************************/
/**
* Nested class OrderedListNode.
*
* Encapsulates the fundamental building block of an OrderedLinkedList
* contains a data item, and references to both the next and previous nodes
* in the list
*/
// TODO: Implement the nested class OrderedListNode (5 points). This nested
// class
// should be similar to the nested class ListNode of the class LinkedList,
// but
// should store a data item of type Comparable rather than Object.
// Remove - for testing only
public static void main(String[] args) {
OrderedLinkedList list = new OrderedLinkedList();
/*list.add("1");
list.add("4");
list.add("3");
list.add("33");
list.add("5");
list.add("2");
list.add("25");*/
list.add("1");
list.add("4");
list.add("3");
list.add("33");
list.add("4");
System.out.println(list.toString());
}
private static class OrderedListNode {
Comparable data;
Comparable theItem;
OrderedListNode next;
OrderedListNode prev;
OrderedListNode(Comparable data) {
this(data, null, null);
}
OrderedListNode(Comparable data, OrderedListNode prev, OrderedListNode next) {
this.theItem = data;
this.next = next;
this.prev = prev;
}
Comparable getData() {
return data;
}
OrderedListNode getNext() {
return next;
}
OrderedListNode getPrev() {
return prev;
}
#Override
public String toString() {
return (String)theItem;
}
}
}
import java.util.*;
public class List {
private Node head;
private int manyNodes;
public List() {
head = null;
manyNodes = 0;
}
public boolean isEmpty() {
return ((head == null) && (manyNodes == 0));
}
public void add(int element) {
if (head == null) {
head = new Node(element, null);
manyNodes++;
} else {
head.addNodeAfter(element);
manyNodes++;
}
}
public boolean remove(int target) {
boolean removed = false;
Node cursor = head;
Node precursor;
if (head == null) {
throw new NoSuchElementException("Cannot remove from empty list");
}
if (head.getInfo() == target) {
head = head.getNodeAfter();
manyNodes--;
removed = true;
} else {
precursor = cursor;
cursor = cursor.getNodeAfter();
while ((cursor != null) && (!removed)) {
if (cursor.getInfo() == target) {
precursor.removeNodeAfter();
manyNodes--;
removed = true;
} else {
precursor = cursor;
cursor = cursor.getNodeAfter();
}
}
}
return removed;
}
public Node getFront() {
return head;
}
public int size() {
return manyNodes;
}
public Node listSort(Node source) {
source = head;
int largest = Integer.MIN_VALUE;
int smallest;
Node front;
while (source != null) {
if (source.getInfo() > largest) {
largest = source.getInfo();
}
source = source.getNodeAfter();
}
front = new Node(Node.find(head, largest).getInfo(), null);
remove(largest);
while (!isEmpty()) {
source = head;
smallest = Integer.MAX_VALUE;
while (source != null) {
if (source.getInfo() <= smallest) {
smallest = source.getInfo();
}
source = source.getNodeAfter();
}
remove(smallest);
front.addNodeAfter(smallest);
}
head = front.reverse(front);
source = head;
return source;
}
public void showList() {
Node cursor = head;
if (cursor == null) {
System.out.println("This list contains no items.");
} else {
while (cursor != null) {
System.out.print(cursor.getInfo() + " ");
cursor = cursor.getNodeAfter();
}
}
}
}//end class List

Categories