I have been working on this code to properly merge and print these two queues, but to no avail. If someone could help point me in the right direction or let me know what I am doing wrong, it would be most appreciated.
Node Class
public class Node<E> {
private E element;
private Node next;
public Node(E element, Node<E> next) {
// Do something here
this.element = element;
this.next = next;
}
public E getElement() {
return element;
}
public void setNextNode(Node<E> next) {
// Do something here
this.next = next;
}
public Node<E> getNextNode() {
// Replace return null with something useful
return next;
}
}
LinkedList class
public class LinkedListQueue<E> implements Queue<E> {
private Node<E> head;
private Node<E> tail;
private int size;
public LinkedListQueue() {
}
public void enqueue(E element) {
Node newNode = new Node(element, null);
if (size == 0) {
head = newNode;
} else {
tail.setNextNode(newNode);
}
tail = newNode;
size++;
}
public E dequeue() {
if (head != null) {
E element = head.getElement();
head = head.getNextNode();
size--;
if (size == 0) {
tail = null;
}
return element;
}
return null;
}
public E first() {
if (head != null) {
return head.getElement();
}
return null;
}
public int getSize() {
return size;
}
public void printList() {
if (head != null) {
Node currentNode = head;
do {
System.out.println(currentNode.toString());
currentNode = currentNode.getNextNode();
} while (currentNode != null);
}
System.out.println();
}
}
Queue Class
public interface Queue<E> {
public void enqueue(E e);
public E dequeue();
public E first();
public int getSize();
public void printList();
}
Main Class
public static void main(String[] args) {
LinkedListQueue q1 = new LinkedListQueue();
q1.enqueue(1);
q1.enqueue(2);
q1.enqueue(3);
q1.enqueue(4);
q1.enqueue(5);
q1.printList();
LinkedListQueue q2 = new LinkedListQueue();
q2.enqueue(6);
q2.enqueue(7);
q2.enqueue(8);
q2.enqueue(9);
q2.printList();
}
public static LinkedListQueue merge(LinkedListQueue q1, LinkedListQueue q2){
LinkedListQueue q3 = new LinkedListQueue();
LinkedListQueue merged = LinkedListQueue.merge(q1,q2);
}
}
Here is what I have put in my LinkedList class
public static LinkedListQueue merge(LinkedListQueue q1, LinkedListQueue q2) {
if (q1 == null) {
return (q2);
} else if (q2 == null) {
return (q1);
}
LinkedListQueue merge = new LinkedListQueue();
merge.enqueue(q1);
merge.enqueue(q2);
return merge;
}
And here is what I have put in my Main. Which now prints the two queues but prints out the node location and not what prints out when I call the other queues.
LinkedListQueue q3 = new LinkedListQueue();
q3 = LinkedListQueue.merge(q1,q2);
q3.printList();
Your problem is in this snippet of code:
public static LinkedListQueue merge(LinkedListQueue q1, LinkedListQueue q2){
LinkedListQueue q3 = new LinkedListQueue();
LinkedListQueue merged = LinkedListQueue.merge(q1,q2); //problematic line
}
Specifically the part LinkedListQueue.merge(q1,q2);. This syntax is saying to call the static method merge defined in the class LinkedListQueue. However, looking in your code for LinkedListQueue, I don't see a static merge method defined.
The way your code is written, it is expecting something like:
public class LinkedListQueue<E> implements Queue<E>{
public static LinkedListQueue<E> merge(LinkedListQueue<E> q1, LinkedListQueue<E> q2){
//definition here
}
//more class code
}
See here for more about static methods.
Related
I am using custom made data structure and, in this project, I am using a doubly LinkedList to implement a blockchain.
so I have made a Main class and a Block class and of course the LinkedList class, the LinkedList class was made to accept data of the type Block so when I try to add elements to my list i pass on a new block with the information the problem is after the first element I don't know how to call the hash value of the previous block.
basically in every block class there should be a hash and the hash of the previous block in block one there is no prev hash so its 0 but the second block and onwards is where I am lost.
this is my block class
import java.util.Date;
public class Block {
public String hash;
public String previousHash;
private String data;
private long timeStamp;
public Block(String data, String previousHash) {
this.data = data;
this.previousHash = previousHash;
this.timeStamp = new Date().getTime();
this.hash = calculateHash();
}
public String calculateHash() {
String calculatehash = StringUtil.applySha256(
previousHash + Long.toString(timeStamp) + data);
return calculatehash;
}
}
this is my doubly LinkedList file
class Node {
private Block data; // node storing int data
private Node nextNode; // the next pointer node, the arrow in drawing
private Node prevNode;
// don't forget the class constructor
public Node(Block data2) {
this.data = data2;
}
// since we made variable private
// to access them we need setters and getters
public Block getData() {
return this.data;
}
public Node getNextNode() {
return this.nextNode;
}
public Node getPrevNode() {
return this.prevNode;
}
public Block setData(Block data) {
return this.data = data;
}
public Node setNextNode(Node nextNode) {
return this.nextNode = nextNode;
}
public Node setpervNode(Node prevNode) {
return this.prevNode = prevNode;
}
#Override
public String toString() {
return "Data: " + this.data;
}
}
public class DoublyLinkedlist {
private Node head;
private Node tail;
private int size = 0;
public DoublyLinkedlist() {
}
public int getSize() {
return this.size;
}
public void addFirst(Block data) {
Node node = new Node(data);
if (this.tail == null && this.head == null) {
this.tail = node;
this.head = node;
} else if (this.head == null) {
this.head = node;
} else {
Node old = this.head;
node.setNextNode(old);
this.head = node;
old.setpervNode(this.head);
}
this.size++;
}
public void addLast(Block data) {
Node node = new Node(data);
if (this.tail == null && this.head == null) {
this.tail = node;
this.head = node;
} else if (this.tail == null) {
this.tail = node;
} else {
Node old = this.tail;
this.tail.setNextNode(node);
this.tail = node;
this.tail.setpervNode(old);
}
this.size++;
}
public Node removeFirst() {
Node removed = this.head;
this.head = this.head.getNextNode();
this.size--;
return removed;
}
#Override
public String toString() {
String output = "[size=" + this.size + "] >> ";
Node fromHead = this.head;
while (fromHead != null) {
output = output + fromHead.getData();
if (fromHead != this.tail)
output = output + " >> ";
fromHead = fromHead.getNextNode();
}
output += "\n";
Node fromTail = this.tail;
while (fromTail != null) {
output = output + fromTail.getData();
if (fromTail != this.head)
output = output + " << ";
fromTail = fromTail.getPrevNode();
}
return output;
}
public boolean contains(Block data) {
Node current = this.head;
while (current != null) {
if (current.getData() == data) {
return true;
}
current = current.getNextNode();
}
return false;
}
public void clear() {
while (this.head != null) {
this.removeFirst();
}
System.out.println("List Is Cleared!");
}
}
and this is my Main class
public class Main {
public static DoublyLinkedlist blockchain = new DoublyLinkedlist();
public static void main(String[] args) {
blockchain.addFirst(new Block("hi i am the first block", "0"));
blockchain.addLast(new Block("yo i am the second block", blockchain.get(blockchain.getSize()-1.hash)));
}
}
i tried using the get method based on a tutorial that was implementing using an arraylist but obviously it's a wrong syntax.
The main program should not have to deal with retrieving hashes, not even with creating blocks. Instead aim for your main code to look like this:
public class Main {
public static DoublyLinkedlist blockchain = new DoublyLinkedlist();
public static void main(String[] args) {
blockchain.addLast("Hi, I am the first block");
blockchain.addLast("Yo, I am the second block");
}
}
Then your other classes would also need some adaptations. In Node I would add a constructor that can take a second argument, so it can establish the link with a previous node:
public Node(Block data, Node prevNode) { // Additional constructor
this.data = data;
this.prevNode = prevNode;
if (prevNode != null) {
prevNode.setNextNode(this);
}
}
In the DoublyLinkedList class, remove the addFirst method: you don't want to add blocks before any existing blocks, as that would invalidate the hashes of the blocks that are already in the list. Blocks should only be added at the end.
The addLast method should take a string instead of a Block instance, and this method can also be used for adding the very first block.
public void addLast(String data) {
tail = new Node(new Block(data, tail != null ? tail.getData().hash : "0"), tail);
if (head == null) head = tail;
size++;
}
i have a problem that the method in LinkedList class don't print anything.. and i'm trying hard to know what's the problem i hope someone help
the main class
public static void main(String[] args) {
LLnode a = new LLnode(10);
LLnode b = new LLnode(20);
LLnode c = new LLnode(50);
LinkedList List1 = new LinkedList();
List1.printAllNodes();
}
}
LinkedList class
public class LinkedList {
private LLnode head;
public LLnode gethead() {
return this.head;
}
public void sethead(LLnode LLnode) {
this.head = LLnode;
}
// Constructor
public LinkedList() {
head = null;
}
// Example Method to check if list is empty
public boolean isEmpty() {
return head == null;
}
public void printAllNodes() {
LLnode helpPtr = head;
while (helpPtr != null) {
System.out.print(helpPtr.getdata() + " ");
helpPtr = helpPtr.getnext();
}
why it dosn't print i tried so hard
This is because you never add any nodes to your LinkedList.
Code could be as follows. Beware, nodes will be added at the beginning of list.
Main class:
public static void main(String[] args) {
LLnode a = new LLnode(10);
LLnode b = new LLnode(20);
LLnode c = new LLnode(50);
LinkedList List1 = new LinkedList();
List1.add(a).add(b).add(c);
List1.printAllNodes();
}
}
LinkedList class:
public class LinkedList {
private LLnode head;
public LLnode gethead() {
return this.head;
}
public void sethead(LLnode LLnode) {
this.head = LLnode;
}
// Constructor
public LinkedList() {
head = null;
}
// Example Method to check if list is empty
public boolean isEmpty() {
return head == null;
}
public LinkedList add(LLnode node){
LLnode oldHead = this.head();
this.head = node;
node.setNext(oldHead);
return this;
}
public void printAllNodes() {
LLnode helpPtr = head;
while (helpPtr != null) {
System.out.print(helpPtr.getdata() + " ");
helpPtr = helpPtr.getnext();
}
}
My project should implement two classes. A basic linked list and a sorted linked list. Everything seems to be working fine except for some reason I can't iterate through the sorted linked list. The class structure is as follows:
public class BasicLinkedList<T> implements Iterable<T> {
public int size;
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
next = null;
}
}
private Node head;
private Node tail;
public BasicLinkedList() {
head = tail = null;
}
//Add, remove method
public Iterator<T> iterator() {
return new Iterator<T>() {
Node current = head;
#Override
public boolean hasNext() {
return current != null;
}
#Override
public T next() {
if(hasNext()){
T data = current.data;
current = current.next;
return data;
}
return null;
}
#Override
public void remove(){
throw new UnsupportedOperationException("Remove not implemented.");
}
};
Now when I test this class it works just fine. The iterator works and I can test it all. The problem is in the sorted linked list class which extends this one. Here's its implementation and a comparator class that I'm using in the constructor:
public class SortedLinkedList<T> extends BasicLinkedList<T>{
private class Node{
private T data;
private Node next;
private Node(T data){
this.data = data;
next = null;
}
}
private Node head;
private Node tail;
private Comparator<T> comp;
public SortedLinkedList(Comparator<T> comparator){
super();
this.comp = comparator;
}
Here's the comparator class and the test I ran in a separate class:
public class intComparator implements Comparator<Integer>{
#Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
}
public static void main(String[] args) {
System.out.println("---------------SortedLinkedList--------------");
SortedLinkedList<Integer> sortedList = new SortedLinkedList<Integer>(new intComparator());
sortedList.add(3);
sortedList.add(5);
sortedList.add(2);
for(int i: sortedList){
System.out.println(i);
}
}
Nothing prints out. I assumed the iterator that was inherited would help me traverse this no problem and clearly its legal because the for-each loop compiles. It's just that nothing gets printed out. I debugged it and all the adding, removing stuff works as expected. It's just that the iterator isn't doing what it's supposed to. Should I create a separate new iterator for this class? But wouldn't that be redundant code since I already inherit it? Help appreciated!
EDIT: Here's the add method for the sorted list
public SortedLinkedList<T> add(T element){
Node n = new Node(element);
Node prev = null, curr = head;
if(head == null){
head = n;
tail = n;
}
//See if the element goes at the very front
else if(comp.compare(n.data, curr.data) <= 0){
n.next = head;
head = n;
}
//See if the element is to be inserted at the very end
else if(comp.compare(n.data, tail.data)>=0){
tail.next = n;
tail = n;
}
//If element is to be inserted in the middle
else{
while(comp.compare(n.data, curr.data) > 0){
prev = curr;
curr = curr.next;
}
prev.next = n;
n.next = curr;
}
size++;
return this;
}
1) SortedLinkedList extends BasicLinkedList but both have
private Node head;
private Node tail
this is wrong. If you want to inherit those field in the sub class, you should mark the variables as protected in the super class and remove them from the subclass.
2) Same goes for private class Node. You are declaring the Node class in both the SortedLinkedList and BasicLinkedList. What you should do is declare it once, (maybe in the super class?) and use the same class in both places. If you do this, the constructor, and the fields should be accessible to both classes. So you will have to change the access modifier (private is what you have now).
I will post below code that works, but I haven't spent any time on the design. Just posting it to demonstrate how you could change the code to make it work. You will have to decide which access modifiers to use and where to put the classes.
import java.util.Comparator;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
System.out.println("---------------SortedLinkedList--------------");
SortedLinkedList<Integer> sortedList = new SortedLinkedList<Integer>(new intComparator());
sortedList.add(3);
sortedList.add(5);
sortedList.add(2);
for (int i : sortedList) {
System.out.println(i);
}
}
}
class BasicLinkedList<T> implements Iterable<T> {
public int size;
class Node {
T data;
Node next;
Node(T data) {
this.data = data;
next = null;
}
}
protected Node head;
protected Node tail;
public BasicLinkedList() {
head = tail = null;
}
// Add, remove method
public Iterator<T> iterator() {
return new Iterator<T>() {
Node current = head;
#Override
public boolean hasNext() {
return current != null;
}
#Override
public T next() {
if (hasNext()) {
T data = current.data;
current = current.next;
return data;
}
return null;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Remove not implemented.");
}
};
}
}
class SortedLinkedList<T> extends BasicLinkedList<T> {
private Comparator<T> comp;
public SortedLinkedList(Comparator<T> comparator) {
super();
this.comp = comparator;
}
public SortedLinkedList<T> add(T element) {
Node n = new Node(element);
Node prev = null, curr = head;
if (head == null) {
head = n;
tail = n;
}
// See if the element goes at the very front
else if (comp.compare(n.data, curr.data) <= 0) {
n.next = head;
head = n;
}
// See if the element is to be inserted at the very end
else if (comp.compare(n.data, tail.data) >= 0) {
tail.next = n;
tail = n;
}
// If element is to be inserted in the middle
else {
while (comp.compare(n.data, curr.data) > 0) {
prev = curr;
curr = curr.next;
}
prev.next = n;
n.next = curr;
}
size++;
return this;
}
}
class intComparator implements Comparator<Integer> {
#Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
}
What's wrong with my LinkedList add method if I want to implement it without a tail field?
public class LinkedList<E> {
private Node<E> head= new Node<E>();
private int size=0;
public void linkedList(){
head=null;
size=0;
}
public void add(E data){
Node<E> currNode=head;
while (currNode.hasNext()){
currNode.setNext(currNode.getNext());
}
Node<E> lastNode= new Node<E>();
lastNode.setItem(data);
lastNode.setNext(null);
currNode.setNext(lastNode);
size++;
}
public void remove(int i){
Node<E> currNode = head;
int index=0;
while (index<i){
currNode.setNext(currNode.getNext());
i++;
}
currNode.setNext(currNode.getNext().getNext());
}
public void print(){
Node<E> currNode = new Node<E>();
do{
System.out.println(currNode.getItem());
} while (!currNode.hasNext());
}
public static void main(String arc[]){
LinkedList<String> ll = new LinkedList<String>();
ll.add("9");
ll.add("b");
ll.add("987");
ll.print();
return;
}
}
Here's the Node class:
public class Node<E> {
private E item;
private Node<E> next;
public Node<E> getNext(){
return this.next;
}
public void setNext(Node<E> n){
this.next=n;
}
public E getItem(){
return this.item;
}
public void setItem(E item){
this.item=item;
}
public boolean hasNext(){
return (this.next != null);
}
}
Edit: Changed the print method to:
public void print(){
Node currNode = head;
while (currNode.hasNext()){
System.out.println(currNode.getItem());
currNode=currNode.getNext();
}
}
and I get this result:
null
9
b
In your add method, don't you mean :
currNode = currNode.getNext();
instead of :
currNode.setNext(currNode.getNext());
? Because the last one has no effect and you are making an infinite loop...
This block will never end
while (currNode.hasNext()) {
currNode.setNext(currNode.getNext());
}
So infinite loop.
Make sure you move the currNode to forward, to reach the loop end by adding crrNode.next() inside the while loop.
My problem is in the add method. I think I know what I want it to do but I can't figure out what type of loop I should use to look through the list. As you can see I started to make a if else loop but I couldn't figure out what I should use as the counter. I'm pretty sure I have the right logic in dealing with the add but I feel like I'm not quite there yet. I was thinking of using compareTo in some fashion.
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node topNode;
private class Node
{
private E data;
private Node nextNode;
public Node(E data)
{
this.data = data;
nextNode = null;
}
}
public OrderedLinkedList()
{
topNode = null;
}
public boolean empty()
{
if(topNode == null)
return true;
return false;
}
public String toString()
{
String myString = "";
Node nextNode = topNode;
while(nextNode != null)
{
myString = topNode + " -> " + nextNode;
nextNode = topNode.nextNode;
}
return myString;
}
public void add(E data)
{
Node myNode = new Node(data);
Node priorNode = topNode;
Node currentNode = topNode;
if(___)
{
priorNode = currentNode;
currentNode = currentNode.nextNode;
}
else
{
priorNode.nextNode = myNode;
myNode.nextNode = currentNode;
}
}
}
Since you don't typically know the length of a linked list until you've walked down it, the usual thing would be to use a while loop (as you've done in your toString() method)
Perhaps using a doubly linked list would be more beneficial. Consider the following alterations to your class:
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node head;
private Node tail;
private class Node
{
private E data;
private Node nextNode;
private Node prevNode;
public Node(E data)
{
this.data = data;
nextNode = null;
prevNode = null;
}
public void setNext(Node node)
{
this.nextNode = node;
}
public Node getNext()
{
return this.nextNode;
}
public void setPrev(Node node)
{
this.prevNode = node;
}
public Node getPrev()
{
return this.prevNode;
}
public E getData()
{
return this.data;
}
public int compareTo(Node that) {
if(this.getData() < that.getData())
{
return -1;
}
else if(this.getData() == that.getData()
{
return 0;
}
else
{
return 1;
}
}
}
public OrderedLinkedList()
{
head = new Node(null);
tail = new Node(null);
head.setNext(tail);
tail.setPrev(head);
}
public boolean empty()
{
if(head.getNext() == tail)
{
return true;
}
return false;
}
public void add(E data) {
Node tmp = new Node(data);
if(this.empty()) {
this.addNodeAfterNode(tmp, head);
} else {
Node that = head.getNext();
// this while loop iterates over the list until finding the correct
// spot to add the new node. The correct spot is considered to be
// when tmp's data is >= that's data, or the next node after 'that'
// is tail. In which case the node is added to the end of the list
while((tmp.compareTo(that) == -1) && (that.getNext() != tail)) {
that = that.getNext();
}
this.addNodeAfterNode(tmp, that);
}
}
private void addNodeAfterNode(Node addNode, Node afterNode)
{
addNode.setNext(afterNode.getNext());
afterNode.getNext().setPrev(addNode);
afterNode.setNext(addNode);
addNode.setPrev(afterNode);
}
}