This one our first class AbstractLinkedList<T>
public abstract class AbstractLinkedList<T> {
public class Node<T> {
public T value;
Node<T> next;
public Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
Node<T> head;
public Node<T> getHead() {
return head;
}
public void addFirst(T value) {
head = new Node<>(value, head);
}
public void addLast(T value){
if(head==null)
head = new Node<>(value, null);
else {
Node<T> node = head;
while (node.next!=null)
node = node.next;
node.next = new Node<>(value, null);
}
}
public void print(){
System.out.println(toString());
}
#Override
public String toString(){
if(head==null) return "boş";
String r="";
Node<T> node=head;
while(node!=null) {
r += node.value + (node.next!=null?" ":"");
node=node.next;
}
return r;
}
public abstract void insertInOrder(T value);
public abstract AbstractLinkedList<T> reverse();
public abstract AbstractLinkedList<T> concatenate(AbstractLinkedList<T> list);
}
This is second one Odev1LinkedList implements Comparable<T>> extends AbstractLinkedList<T>
public class Odev1LinkedList<T extends Comparable<T>> extends AbstractLinkedList<T> {
#Override
public AbstractLinkedList<T> reverse() {
Odev1LinkedList a = new Odev1LinkedList();
Node<T> root = new Node(this, head);
Node<T> iter = root;
Node<T> temp ;
a.head = null;
do {
temp = iter;
a.addFirst(temp.value);
iter = iter.next;
}while (temp !=root );
return a;
}
When I run this code example.reverse should make reverse and return LinkedList without changing ORIGINAL LinkedList.
But its return without reversing
You can't use the < operator on arbitrary objects. It's only defined for primitive numbers. Take a look into the specification.
If your object of type T implements Comparable<T> you can use head.value.compareTo(value) < 0.
If you want your objects of type T to implement Comparable<T> you have to go to your class declaration and write
public class MyLinkedList<T extends Comparable<T>> { ... }
Related
I want to write a custom iterator for BinaryTree. This iterator should return Node<?> objects. I get compile error in file InorderIterator in lines with recursive call to fillList: fillList(currentNode.getLeft());
The error is: Error:(14, 37) java: incompatible types: rclib.Node cannot be converted to T
Can somebody explain me why my approach doesn't work? Or how to fix it
Node.java
package rclib;
public class Node<T extends Comparable<T>> {
T key;
Node<T> left;
Node<T> right;
public Node(T key, Node left, Node right) {
this.key = key;
this.left = left;
this.right = right;
}
public Node(T key) {
this(key, null, null);
}
public Node<T> getLeft() {
return left;
}
public Node<T> getRight() {
return right;
}
public T getKey() {
return key;
}
}
InorderIterator.java
package rclib;
import java.util.*;
public class InorderIterator<T extends Node<?>> implements Iterator<T> {
LinkedList<T> list;
public InorderIterator(T root) {
list = new LinkedList<T>();
fillList(root);
}
public void fillList(T currentNode) {
if (currentNode == null) return;
fillList(currentNode.getLeft());
list.add(currentNode);
fillList(currentNode.getRight());
}
#Override
public boolean hasNext() {
return !list.isEmpty();
}
#Override
public T next() {
return list.removeFirst();
}
}
AVLTree.java
package rclib;
public class AVLTree<T extends Comparable<T>> implements Iterable<Node<T>>{
private Node<T> root;
#Override
public Iterator<Node<T>> iterator() {
return new InorderIterator<Node<T>>(root);
}
}
You should perhaps do something like that:
package rclib;
import java.util.*;
public class InorderIterator<T extends Comparable<T>> implements Iterator<Node<T>> {
LinkedList<Node<T>> list;
public InorderIterator(Node<T> root) {
list = new LinkedList<Node<T>>();
fillList(root);
}
public void fillList(Node<T> currentNode) {
if (currentNode == null) return;
fillList(currentNode.getLeft());
list.add(currentNode);
fillList(currentNode.getRight());
}
#Override
public boolean hasNext() {
return !list.isEmpty();
}
#Override
public Node<T> next() {
return list.removeFirst();
}
}
You have to explicitly specify that you use Node and not ? extends Node which might finally be not qualified for the correct usage.
public static class InorderIterator<T extends Comparable<T>> implements Iterator<Node<T>> {
LinkedList<Node<T>> list;
public InorderIterator(Node<T> root) {
list = new LinkedList<>();
fillList(root);
}
public void fillList(Node<T> currentNode) {
if (currentNode == null) return;
fillList(currentNode.getLeft());
list.add(currentNode);
fillList(currentNode.getRight());
}
#Override
public boolean hasNext() {
return !list.isEmpty();
}
#Override
public Node<T> next() {
return list.removeFirst();
}
}
I am currently trying to write a method insertEnd that inserts a node at the end of a list, using the tail reference. As I am still learning about it, I do not know how I can approach this. If you have any suggestions or solutions, please could you let me know as it will help me greatly.
package lib;
public class LinkedList {
private Node head;
private Node tail;
public LinkedList(Node h){
head = h;
}
public Node getHead(){
return head;
}
public Node getTail(){
return tail;
}
public void setHead(Node n){
head = n;
}
public void insertEnd(Node newNode){
}
public class ListApp {
public static void main(String[] args){
Node n4 = new Node("green", null);
Node n3 = new Node("orange", n4);
Node n2 = new Node("blue", n3);
Node n1 = new Node("red", n2);
package lib;
public class Node {
private String item;
private Node nextItem;
public Node(String str, Node n){
item = str;
nextItem = n;
}
public String getItem(){
return item;
}
public void setItem(String str){
item = str;
}
public Node next(){
return nextItem;
}
public void setNext(Node n){
nextItem = n;
}
public String getHead(){
return item;
}
}
Here's one possible solution:
public void insertEnd(Node newNode){
newNode.setNext(null);
if (tail == null) {
tail = newNode;
head = newNode;
} else {
tail.setNext(newNode);
tail = newNode;
}
}
Assuming your Node, holds a reference to next,
public class Node<E>{
private E ele;
private Node<E> next;
P.S: Java already does have the LinkedList implemented for our convenience.
Currently as an exercise to practicing SOLID principles and basic data structures, I am trying to implement linked list type structures with as much code reuse as possible. Currently, I have:
package structures.linked;
public class SingleNode<T> {
private T data;
private SingleNode<T> next;
public SingleNode(T data, SingleNode<T> next) {
this.data = data;
this.next = next;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public SingleNode<T> getNext() {
return next;
}
public void setNext(SingleNode<T> next) {
this.next = next;
}
}
and...
package structures.linked;
public class DoubleNode<T> extends SingleNode<T> {
private DoubleNode<T> prev;
public DoubleNode(T data, DoubleNode<T> next, DoubleNode<T> prev) {
super(data, next);
this.prev = prev;
}
public DoubleNode<T> getPrev() {
return prev;
}
public void setPrev(DoubleNode<T> prev) {
this.prev = prev;
}
public DoubleNode<T> getNext() {
return (DoubleNode<T>) super.getNext();
}
public void setNext(DoubleNode<T> next) {
super.setNext(next);
}
}
It seems to me that getNext() inside of DoubleNode<T> is a violation of Liskov's substitution principle. Is this the case? Is there a better way to implement this while still reusing the code in SingleNode<T> and without breaking SOLID principles?
You can do this by using an abstract class with additional generic parameter:
public abstract class AbstracteNode<T, B extends AbstracteNode<T, ?>> {
private T data;
private B nextNode;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void setNext(B inNextNode){
this.nextNode = inNextNode;
}
public B getNext() {
return nextNode;
}
}
Then extending it with the correct types for B:
(In case of SingleNode you do this only for the reason that developers using it have only to provide T)
public class SingleNode<T> extends AbstracteNode<T, SingleNode<T>>{}
And
public class DoubleNode<T> extends AbstracteNode<T, DoubleNode<T>> {
private DoubleNode<T> previousNode;
public DoubleNode<T> getPrevious() {
return previousNode;
}
public void setPrevious(DoubleNode<T> inPreviousNode) {
this.previousNode = inPreviousNode;
}
}
Now your test should work without code duplication and without casting:
public class Test {
public static void main(String argv[]){
SingleNode<Integer> singleNode = new SingleNode<>();
SingleNode<Integer> nextForSingle = singleNode.getNext();
DoubleNode<Double> doubleNode = new DoubleNode<>();
DoubleNode<Double> previousForDouble = doubleNode.getPrevious();
DoubleNode<Double> nextForDouble = doubleNode.getNext();
}
}
The problem comes in the toString method of the following code:
import java.util.*;
public class LinkedDeque<T> // implements Deque<T>
{
private Node head;
private Node tail;
private int size;
private class Node // Node class
{
T info;
Node next;
Node prev;
private Node (T info, Node prev, Node next)
{
this.info = info;
this.prev = prev;
this.next = next;
}
private T getInfo()
{
return this.info;
}
private Node getNext()
{
return this.next;
}
private Node getPrev()
{
return this.prev;
}
}
public LinkedDeque ()
{
this.head = null;
this.tail = null;
this.size = 0;
}
public static void main()
{
}
public int size ()
{
Node count = head;
while(count.getNext() != null)
{
size++;
count = count.getNext();
}
return size;
}
public String toString()
{
return this.getInfo();
}
public boolean isEmpty()
{
return size() == 0;
}
}
My compiler keeps giving me an error saying that the getInfo method is missing. Any help would be appreciated! Initially, I thought this was due to the fact that the Node class was private, but the Node getNext() method works fine in the method size().
The toString method is a member of LinkedDeque not Node. LinkedDeque does not have a getInfo method.
Not sure what it is you were trying to achieve, but you may consider moving that method into the Node class...
In my program, I write my own LinkedList class. And an instance, llist.
To use it in foreach loop as following, LinkedList needs to implement Iterable?
for(Node node : llist) {
System.out.print(node.getData() + " ");
}
Here following is my LinkedList class. Please let me know how can I make it Iterable?
public class LinkedList implements Iterable {
private Node head = null;
private int length = 0;
public LinkedList() {
this.head = null;
this.length = 0;
}
LinkedList (Node head) {
this.head = head;
this.length = 1;
}
LinkedList (LinkedList ll) {
this.head = ll.getHead();
this.length = ll.getLength();
}
public void appendToTail(int d) {
...
}
public void appendToTail(Node node) {
...
}
public void deleteOne(int d) {
...
}
public void deleteAll(int d){
...
}
public void display() {
...
}
public Node getHead() {
return head;
}
public void setHead(Node head) {
this.head = head;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public boolean isEmpty() {
if(this.length == 0)
return true;
return false;
}
}
Implement the only method of the Iterable interface, iterator().
You will need to return an instance of Iterator in this method. Typically this is done by creating an inner class that implements Iterator, and implementing iterator by creating an instance of that inner class and returning it.