I have implemented the ability to undo/redo adding a number using the command pattern as seen here:
public void start(Stage stage) {
try {
CommandManager command = new CommandManager();
command.addCommand(new CommandChanger("2"));
command.undo();
command.redo();
}
}
This correctly undo's and redo's the 2. But, how can I do this with a JavaFX button click?
For reference, here is my CommandManager Class:
public class CommandManager {
private Node currentIndex = null;
private Node parentNode = new Node();
public CommandManager(){
currentIndex = parentNode;
}
public CommandManager(CommandManager manager){
this();
currentIndex = manager.currentIndex;
}
public void clear(){
currentIndex = parentNode;
}
public void addCommand(Command command){
Node node = new Node(command);
currentIndex.right = node;
node.left = currentIndex;
currentIndex = node;
}
public boolean canUndo(){
return currentIndex != parentNode;
}
public boolean canRedo(){
return currentIndex.right != null;
}
public void undo(){
//validate
if ( !canUndo() ){
throw new IllegalStateException("Cannot undo. Index is out of range.");
}
//undo
currentIndex.command.undo();
//set index
moveLeft();
}
private void moveLeft(){
if ( currentIndex.left == null ){
throw new IllegalStateException("Internal index set to null.");
}
currentIndex = currentIndex.left;
}
private void moveRight(){
if ( currentIndex.right == null ){
throw new IllegalStateException("Internal index set to null.");
}
currentIndex = currentIndex.right;
}
public void redo(){
//validate
if ( !canRedo() ){
throw new IllegalStateException("Cannot redo. Index is out of range.");
}
//reset index
moveRight();
currentIndex.command.redo();
}
private class Node {
private Node left = null;
private Node right = null;
private final Command command;
public Node(Command c){
command = c;
}
public Node(){
command = null;
}
}
}
Related
I am trying to get a binary search tree to balance.
I balance the tree after the insert method.
I hope someone here can guide me through this.
The method is balanceTheTree(...).
I did a recursive method, I don't know if it's the best solution
public class BinaryTreeTable<E extends Comparable<E>, T> implements Table<E, T> {
private Node root;
public BinaryTreeTable() {
this.root = new Node(null, null, null);
}
#Override
public boolean insert(E key, T data) {
boolean ret;
if (this.root.key == null) {
Node toInsert = new Node(null, key, data);
this.root = toInsert;
ret = true;
} else {
Node father = this.seekFather(key);
if (father == null) {
ret = false;
} else {
Node toInsert = new Node(father, key, data);
if (key.compareTo(father.key) > 0) {
father.rSon = toInsert;
ret = true;
balanceTheTree(toInsert);
} else if (key.compareTo(father.key) < 0) {
father.lSon = toInsert;
ret = true;
balanceTheTree(toInsert);
} else {
ret = false;
}
}
}
return ret;
}
private void rightRotation(Node theN) {
Node k2 = theN.rSon;
theN.rSon = k2.lSon;
k2.lSon = theN;
}
private void leftRotation(Node theN) {
Node k1 = theN.lSon;
theN.lSon = k1.rSon;
k1.rSon = theN;
}
private void leftRightRotation(Node theN) {
leftRotation(theN.rSon);
rightRotation(theN);
}
private void rightLeftRotation(Node theN) {
rightRotation(theN.lSon);
leftRotation(theN);
}
private void balanceTheTree(Node theN) {
if (theN == null) {
} else {
if (Math.abs(Math.subtractExact(computeH(theN.rSon), computeH(theN.lSon))) > 1) {
System.out.println("A droite " + theN.getLabel());
if (computeH(theN.lSon) > computeH(theN.rSon)) {
leftRotation(theN);
} else {
leftRightRotation(theN);
}
} else if (Math.abs(Math.subtractExact(computeH(theN.lSon), computeH(theN.rSon))) > 1) {
System.out.println("A gauche");
} else {
balanceTheTree(theN.rSon);
balanceTheTree(theN.lSon);
}
}
}
private int computeH(Node theN) {
int ret = 1;
if (theN == null) {
ret = 0;
} else if ((theN.lSon != null) && (theN.rSon == null)) {
ret = computeH(theN.lSon) + 1;
} else if ((theN.lSon == null) && (theN.rSon != null)) {
ret = computeH(theN.rSon) + 1;
} else if ((theN.lSon != null) && (theN.rSon != null)) {
ret = Math.max(computeH(theN.lSon), computeH(theN.rSon)) + 1;
}
return ret;
}
public class Node {
// Attributs
private Node lSon ;
private Node rSon ;
private Node father ;
private T theValue ;
private E key ;
// Constructeur
public Node (Node father, E key, T theValue) {
this.father = father;
this.key = key;
this.theValue = theValue;
}
public String getLabel() {
return String.valueOf(key);
}
public Node getLeft() {
return lSon;
}
public Node getRight() {
return rSon;
}
public Node clone() {
return new Node(this.father, this.key, this.theValue);
}
}
}
The computeH() method allows me to know the size of a node
The insertion method works correctly.
The tree i want to balance
public static void main(String[] args) {
BinaryTreeTable binaryTreeTable = new BinaryTreeTable();
binaryTreeTable.insert(10, "Test");
binaryTreeTable.insert(5, "Test");
binaryTreeTable.insert(7, "Test");
binaryTreeTable.insert(3, "Test");
binaryTreeTable.insert(4, "Test");
binaryTreeTable.insert(15, "Test");
binaryTreeTable.insert(19, "Test");
binaryTreeTable.insert(16, "Test");
binaryTreeTable.insert(20, "Test");
binaryTreeTable.showTree();
}
Hello this is my linked list without implementing java.util.linkedlist
I'd like to create a method that display recursively all of the elements in my linked list but I have no idea how to, my method doesn't have any parameters so I don't know how to get to the next value when calling the method itself
public class Pokemon {
private String name;
private String type;
private int niveau;
public Pokemon(String name, String type) {
this.name = name;
this.type = type;
this.niveau = (int) (Math.random() * (1 * 1 - 100) + 100);
}
public void display() {
System.out.println(this.name);
}
public class Trainer {
public final String name;
private Pokeball head;
public Trainer(String name) {
this.name = name;
}
public void addPokemon(Pokemon pok) {
if (this.head != null) {
this.head.addPokemon(pok);
} else {
this.head = new Pokeball(pok);
}
}
public void display() {
if (this.head == null)
return;
else {
this.head.display();
}
}
public class Pokeball {
private Pokemon pok;
private Pokeball next;
public Pokeball(Pokemon pok) {
this.pok = pok;
}
public Pokeball(Pokemon pok, Pokeball next) {
this.pok = pok;
this.next = next;
}
public void addPokemon(Pokemon pok) {
Pokeball current = this;
while (current.next != null) {
current = current.next;
}
current.next = new Pokeball(pok);
}
public void display() {
Pokeball current = this;
if (current.next == null){
return;
} else {
// ....
}
}
I assume this is for Pokeballclass, Why you would like to display using recursion ? why not iteration? Your Trainer class doesn't create a linked list, it has no next.
public void display() {
Pokeball current = this; //Note that this won't change your 'this'
while ( current != null ) {
System.out.print( current.display() + "->" );
current = current.next;
}
}
Recursive:
private void display_recurse( Pokeball current ) {
if ( current == null )
return;
System.out.print( current.display() + "->" );
display_recurse( current.next);
}
You may call this like:
public void display() {
display_recurse( this );
}
Usually this is accomplished using a private helper function that does have a parameter.
public void display() {
Pokeball current = this;
display(current);
}
private void display(Pokeball toDisplay) {
if(toDisplay == null) {
return;
} else {
// code to display current here
// ...
display(toDisplay.next);
}
}
This is my user class and i found that i have to use the compareTo method but i need a method which adding in a Rb list.
There is an already existed add method and i have make a similar which order the users alphabetically.
import java.lang.Comparable;
public class LaptopUser implements Comparable<LaptopUser>
{
private String username;
private String password;
public LaptopUser(String username,String password)
{
this.username=username;
this.password=password;
}
public String getUsername(){
return username ;
}
public String getPass()
{
return password;
}
public String toString(){
return(username+","+password);
}
#Override
public int compareTo(LaptopUser n)
{
if(this.toString().compareTo(n.toString())>0)
{
return 1;
}
else if(this.toString().compareTo(n.toString())<0)
{
return -1;
}
return 0;
}
public boolean equals(LaptopUser p)
{
return(this.toString().equals(p.toString()));
}
}
public class ReferenceBasedList implements ListInterface
{
private ListNode head;
private ListNode tail;
int numItems;
public ReferenceBasedList()
{
head = tail = null;
numItems = 0;
}
public int size()
{
return numItems;
}
public boolean isEmpty()
{
return (numItems == 0);
}
public void removeAll()
{
head = tail = null;
numItems = 0;
}
private ListNode find(int index)
{
ListNode curr = head;
for (int skip = 1; skip < index; skip++)
curr = curr.getNext();
return curr;
}
public Object get(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 1 && index <= numItems)
{
ListNode curr = find(index);
return curr.getItem();
}
else
{
throw new ListIndexOutOfBoundsException(
"List index out of bounds exception on get");
}
}
public void add(int index, Object newDataItem)
throws ListIndexOutOfBoundsException
{
if (index >= 1 && index <= numItems+1)
{
if ( index == 1 )
{
ListNode newNode = new ListNode(newDataItem, head);
head = newNode;
if (tail==null)
tail = head;
}
else if ( index==numItems+1 )
{
ListNode newNode = new ListNode(newDataItem);
tail.setNext(newNode);
tail = newNode;
}
else
{
ListNode prev = find(index-1);
ListNode newNode = new ListNode(newDataItem, prev.getNext());
prev.setNext(newNode);
}
numItems++;
}
else
{
throw new ListIndexOutOfBoundsException(
"List index out of bounds exception on add");
}
}
public void insert(Object newDataItem)
{
this.add(1,newDataItem);
}
public void append(Object newDataItem)
{
this.add(numItems+1,newDataItem);
}
public Object showFront()
{
return this.get(1);
}
public Object showLast()
{
return this.get(numItems);
}
public void remove(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 1 && index <= numItems)
{
if (index == 1)
{
head = head.getNext();
if (head == null)
tail = null;
}
else
{
ListNode prev = find(index-1);
ListNode curr = prev.getNext();
prev.setNext(curr.getNext());
if (index == numItems)
tail = prev;
}
numItems--;
}
else
{
throw new ListIndexOutOfBoundsException(
"List index out of bounds exception on remove");
}
}
public boolean exists(Object dataItem)
{
for (ListNode tmp=head; tmp!=null; tmp=tmp.getNext())
if (tmp.getItem().equals(dataItem))
return true;
return false;
}
public Object removeLast() throws ListException
{
if (isEmpty())
throw new ListException("The linked list is empty");
else
{
Object lastDataItem = tail.getItem();
if (head == tail)
head = tail = null;
else
{
ListNode tmp = head;
while (tmp.getNext().getNext() != null)
tmp = tmp.getNext();
tail = tmp;
tail.setNext(null);
}
numItems--;
return lastDataItem;
}
}
public Object removeFront() throws ListException
{
if (isEmpty())
throw new ListException("The linked list is empty");
else
{
Object frontDataItem = head.getItem();
head = head.getNext();
if (head == null)
tail = null;
numItems--;
return frontDataItem;
}
}
}
You can use the Collections.binarySearch method to find at what index a LaptopUser should be added to a List in order for it to be alphabetically ordered.
SortedList:
public class SortedList implements Iterable<LaptopUser> {
public List<LaptopUser> users = new ArrayList<LaptopUser>();
public void add(LaptopUser user) {
int index = Collections.binarySearch(users, user);
if (index < 0)
users.add(-index - 1, user);
else
users.add(index, user);
}
#Override
public Iterator<LaptopUser> iterator() {
return users.iterator();
}
Example Code:
public class LaptopUser implements Comparable<LaptopUser> {
public String username;
public String password;
public LaptopUser(String username, String password) {
this.username = username;
this.password = password;
}
#Override
public int compareTo(LaptopUser o) {
return toString().compareTo(o.toString());
}
#Override
public String toString() {
return username.concat(password);
}
}
public Sorted() {
LaptopUser a =new LaptopUser("a", "password");
LaptopUser b =new LaptopUser("b", "password");
LaptopUser c =new LaptopUser("c", "password");
SortedList list = new SortedList();
list.add(c);
list.add(a);
list.add(b);
for(LaptopUser user : list)
System.out.println(user);
}
public static void main(String[] args) {
new Sorted();
}
Output:
apassword
bpassword
cpassword
This button handler's purpose is to search a binary tree for a location to a record inside a random access file. The method fillInfoField is there to populate the GUI with the returned data. Any help will be greatly appreciated!
private class HandlerSSN implements ActionListener {
public void actionPerformed(ActionEvent event) {
String ssnReqStr = tfReqSSN.getText();
String num;
int ssn;
BalanceOnDemand.Node currNode = null;
BalanceOnDemand myTree = new BalanceOnDemand();
if (ssnReqStr.length() == 0) {
tfMsg.setText("Lookup by Name (partial match allowed)");
tfReqName.requestFocus();
return;
} else {
try {
raf.seek(0);
myTree.root = (BalanceOnDemand.Node) ois.readObject();
num = ssnReqStr.replaceAll("[^0-9]", "");
ssn = Integer.parseInt(num);
currNode = myTree.find(ssn);
System.out.println(currNode);
if(currNode != null){
raf.seek(currNode.loc - REC_LEN);
fillInfoFields(readCurrRec());
}else{
System.out.println("Test");
tfMsg.setText("SSN \"" + tfReqSSN.getText() + "\" was not found");
return;
}
} catch (IOException | ClassNotFoundException e) {
System.out.println(currNode.id);
tfMsg.setText("SSN \"" + tfReqSSN.getText()
+ "\" was not found");
}
}
}
}
Here is the find method if you would like to see it.
public Node find(int key)
{
Node current;
current = root;
while(current!=null && current.id!=key)
{
if(key<current.id){
current = current.left;
}else{
current = current.right;
}
}
return current;
}
class Node implements Serializable
{
private static final long serialVersionUID = 1L;
public int id;
public int loc;
public Node left;
public Node right;
public Node(int i,int i2)
{
id = i;
loc = i2;
left = null;
right = null;
}
}
I solved this on my own. I needed to re-instantiate each of the input streams. Here is the code I added to the top of the button handler.
try
{
fis = new FileInputStream("treeObject.dat");
ois = new ObjectInputStream(fis);
}
catch (IOException e)
{
e.printStackTrace();
}
I have implemented a Linked List into Java. I have created everything, but I am having difficulty removing a specific node with specific data. It is throwing a NullPointerException. I believe, I am getting a NullPointerException because the next node is null. If someone could please point me in the right direction that would be great.
Input
anything
one
two
three
exception:
Exception in thread "main" java.lang.NullPointerException
at LinkedList.remove(LinkedList.java:28)
at Main.main(Main.java:29)
Classes:
Linked list class
public class LinkedList {
// fields
private Node head;
private Node last;
private int size = 0;
// constructor, used when the class is first called
public LinkedList() {
head = last = new Node(null);
}
// add method
public void add(String s) {
last.setNext(new Node(s));
last = last.getNext();
size++;
}
// remove method, if it returns false then the specified index element doens not exist
// otherwise will return true
public boolean remove(String data) {
Node current = head;
last = null;
while(current != null) {
if(current.getData().equals(data)) {
current = current.getNext();
if(last == null) {
last = current;
}else {
last.getNext().setNext(current);
size--;
return true;
}
}else {
last = current;
current = current.getNext();
}
}
return false;
}
//will return the size of the list - will return -1 if list is empty
public int size() {
return size;
}
// will check if the list is empty or not
public boolean isEmpty() {
return true;
}
// #param (index) will get the data at specified index
public String getData(int index) {
if(index <= 0) {
return null;
}
Node current = head.getNext();
for(int i = 1;i < index;i++) {
if(current.getNext() == null) {
return null;
}
current = current.getNext();
}
return current.getData();
}
//#param will check if the arguement passed is in the list
// will return true if the list contains arg otherwise false
public boolean contains(String s) {
for(int i = 1;i<=size();i++) {
if(getData(i).equals(s)) {
return true;
}
}
return false;
}
//#return contents of the list - recursively
public String toString() {
Node current = head.getNext();
String output = "[";
while(current != null) {
output += current.getData()+",";
current = current.getNext();
}
return output+"]";
}
//#return first node
public Node getHead() {
return head;
}
// #return (recursively) list
public void print(Node n) {
if(n == null) {
return;
}else {
System.out.println(n.getData());
print(n.getNext());
}
}
}
Main
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException{
LinkedList list = new LinkedList(); // declaring main linked list
LinkedList b_List = new LinkedList(); // declaring the backup list
String input = null;
// getting input from user, will stop when user has entered 'fin'
while(!(input = br.readLine()).equals("fin")) {
list.add(input); // adding to main list
b_List.add(input);
}
list.print(list.getHead().getNext());
System.out.println("Input Complete.");
if(list.size() == 1) {
System.out.println("You have entered only one name. He/She is the survior");
}else {
System.out.println("Enter the name(s) would like to remove: ");
while(b_List.size() != 1) {
String toRemove = br.readLine();
b_List.remove(toRemove);
}
}
System.out.println("The contestants were: ");
list.print(list.getHead().getNext());
}
}
node
public class Node {
// Fields
private String data;
private Node next;
// constructor
public Node(String data) {
this(data,null);
}
// constructor two with Node parameter
public Node(String data, Node node) {
this.data = data;
next = node;
}
/**
* Methods below return information about fields within class
* */
// #return the data
public String getData() {
return data;
}
// #param String data to this.data
public void setData(String data) {
this.data = data;
}
// #return next
public Node getNext() {
return next;
}
// #param Node next set to this.next
public void setNext(Node next) {
this.next = next;
}
}
First of all, your head is just a before-first marker so you shouldn't start the remove check from it.
Second, your remove method fails if node data is null
Third - your implementation is broken anyway because of last.getNext().setNext(current) - it won't link previous node with next, it will link current to next (i.e. will do nothing)
Fourth - it still fails to remove first element because of mysterious operations with last...
Correct implementation of remove would be something like this:
public boolean remove(String data){
Node previous = head;
Node current = head.getNext();
while (current != null) {
String dataOld = current.getData();
if ((dataOld == null && data == null) || (dataOld != null && dataOld.equals(data))) {
Node afterRemoved = current.getNext();
previous.setNext(afterRemoved);
if (afterRemoved == null) { // i.e. removing last element
last = previous;
}
size--;
return true;
} else {
previous = current;
current = current.getNext();
}
}
return false;
}
Here we can see the simple implementation of LinkedList with iterator
class LinkedList implements Iterable{
private Node node;
public void add(Object data){
if(!Optional.ofNullable(node).isPresent()){
node = new Node();
node.setData(data);
}else{
Node node = new Node();
node.setData(data);
Node lastNode = getLastNode(this.node);
lastNode.setNext(node);
}
}
private Node getLastNode(Node node){
if(node.getNext()==null){
return node;
}else{
return getLastNode(node.getNext());
}
}
class Node{
private Object data;
private Node next;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public Iterator iterator() {
return new NodeIterator();
}
class NodeIterator implements Iterator{
private Node current;
public boolean hasNext() {
if(current == null){
current = node;
return Optional.ofNullable(current).isPresent();
}else{
current = current.next;
return Optional.ofNullable(current).isPresent();
}
}
public Node next() {
return current;
}
}
}
public class LinkedListImpl {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("data1");
linkedList.add("data2");
linkedList.add("data3");
for(LinkedList.Node node: linkedList){
System.out.println(node.getData());
}
}
}
Here is Full Implementaion of Linked List
including insertion,deletion,searching,reversing,swaping,size,display and various important operations of linked list
import java.util.NoSuchElementException;
import java.util.Scanner;
class Node<T> {
public Node<T> next;
public T data;
public Node() {
}
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
#Override
public String toString() {
return "Node [next=" + next + ", data=" + data + "]";
}
}
class LinkedList<T> {
Node<T> start = null;
Node<T> end = null;
public void insertAtStart(T data) {
Node<T> nptr = new Node<T>(data, null);
if (empty()) {
start = nptr;
end = start;
} else {
nptr.next = start;
start = nptr;
}
display();
}
public void insertAtEnd(T data) {
Node<T> nptr = new Node<T>(data, null);
if (empty()) {
insertAtStart(data);
return;
} else {
end.next = nptr;
end = nptr;
}
display();
}
public void insertAtPosition(int position, T data) {
if (position != 1 && empty())
throw new IllegalArgumentException("Empty");
if (position == 1) {
insertAtStart(data);
return;
}
Node<T> nptr = new Node<T>(data, null);
if (position == size()) {
Node<T> startPtr = start;
Node<T> endPtr = startPtr;
while (startPtr.next != null) {
endPtr = startPtr;
startPtr = startPtr.next;
}
endPtr.next = nptr;
nptr.next = end;
} else {
position -= 1;
Node<T> startPtr = start;
for (int i = 1; i < size(); i++) {
if (i == position) {
Node<T> temp = startPtr.next;
startPtr.next = nptr;
nptr.next = temp;
}
startPtr = startPtr.next;
}
}
display();
}
public void delete(int position) {
if (empty())
throw new IllegalArgumentException("Empty");
if (position == 1) {
start = start.next;
} else if (position == size()) {
Node<T> startPtr = start;
Node<T> endPtr = start;
while (startPtr.next != null) {
endPtr = startPtr;
startPtr = startPtr.next;
}
endPtr.next = null;
end = endPtr;
} else {
position -= 1;
Node<T> startPtr = start;
for (int i = 1; i <= position; i++) {
if (i == position) {
Node<T> temp = startPtr.next.next;
startPtr.next = temp;
}
startPtr = startPtr.next;
}
}
display();
}
public int index(T data) {
if (empty())
throw new IllegalArgumentException("Empty");
return index(start, data, 0);
}
private int index(Node<T> link, T data, int index) {
if (link != null) {
if (link.data == data) {
return index;
}
return index(link.next, data, ++index);
}
return -1;
}
public void replace(int position, T data) {
if (empty())
throw new IllegalArgumentException("Empty");
if (position == 1)
start.data = data;
else if (position == size())
end.data = data;
else {
Node<T> startPtr = start;
for (int i = 1; i <= position; i++) {
if (i == position)
startPtr.data = data;
startPtr = startPtr.next;
}
}
display();
}
public void replaceRecursively(int position, T data) {
replaceRecursively(start, position, data, 1);
display();
}
private void replaceRecursively(Node<T> link, int position, T data, int count) {
if (link != null) {
if (count == position) {
link.data = data;
return;
}
replaceRecursively(link.next, position, data, ++count);
}
}
public T middle() {
if (empty())
throw new NoSuchElementException("Empty");
Node<T> slowPtr = start;
Node<T> fastPtr = start;
while (fastPtr != null && fastPtr.next != null) {
slowPtr = slowPtr.next;
fastPtr = fastPtr.next.next;
}
return slowPtr.data;
}
public int occurence(T data) {
if (empty())
throw new NoSuchElementException("Empty");
return occurence(start, data, 0);
}
private int occurence(Node<T> link, T data, int occurence) {
if (link != null) {
if (link.data == data)
++occurence;
return occurence(link.next, data, occurence);
}
return occurence;
}
public void reverseRecusively() {
reverseRecusively(start);
swapLink();
display();
}
private Node<T> reverseRecusively(Node<T> link) {
if (link == null || link.next == null)
return link;
Node<T> nextLink = link.next;
link.next = null;
Node<T> revrseList = reverseRecusively(nextLink);
nextLink.next = link;
return revrseList;
}
public void reverse() {
if (empty())
throw new NoSuchElementException("Empty");
Node<T> prevLink = null;
Node<T> currentLink = start;
Node<T> nextLink = null;
while (currentLink != null) {
nextLink = currentLink.next;
currentLink.next = prevLink;
prevLink = currentLink;
currentLink = nextLink;
}
swapLink();
display();
}
private void swapLink() {
Node<T> temp = start;
start = end;
end = temp;
}
public void swapNode(T dataOne, T dataTwo) {
if (dataOne == dataTwo)
throw new IllegalArgumentException("Can't swap " + dataOne + " and " + dataTwo + " both are same");
boolean foundDataOne = false;
boolean foundDataTwo = false;
Node<T> dataOnePtr = start;
Node<T> dataOnePrevPtr = start;
while (dataOnePtr.next != null && dataOnePtr.data != dataOne) {
dataOnePrevPtr = dataOnePtr;
dataOnePtr = dataOnePtr.next;
}
Node<T> dataTwoPtr = start;
Node<T> dataTwoPrevPtr = start;
while (dataTwoPtr.next != null && dataTwoPtr.data != dataTwo) {
dataTwoPrevPtr = dataTwoPtr;
dataTwoPtr = dataTwoPtr.next;
}
if (dataOnePtr != null && dataOnePtr.data == dataOne)
foundDataOne = true;
if (dataTwoPtr != null && dataTwoPtr.data == dataTwo)
foundDataTwo = true;
if (foundDataOne && foundDataTwo) {
if (dataOnePtr == start)
start = dataTwoPtr;
else if (dataTwoPtr == start)
start = dataOnePtr;
if (dataTwoPtr == end)
end = dataOnePtr;
else if (dataOnePtr == end)
end = dataTwoPtr;
Node<T> tempDataOnePtr = dataOnePtr.next;
Node<T> tempDataTwoPtr = dataTwoPtr.next;
dataOnePrevPtr.next = dataTwoPtr;
dataTwoPtr.next = tempDataOnePtr;
dataTwoPrevPtr.next = dataOnePtr;
dataOnePtr.next = tempDataTwoPtr;
if (dataOnePtr == dataTwoPrevPtr) {
dataTwoPtr.next = dataOnePtr;
dataOnePtr.next = tempDataTwoPtr;
} else if (dataTwoPtr == dataOnePrevPtr) {
dataOnePtr.next = dataTwoPtr;
dataTwoPtr.next = tempDataOnePtr;
}
} else
throw new NoSuchElementException("Either " + dataOne + " or " + dataTwo + " not in the list");
display();
}
public int size() {
return size(start, 0);
}
private int size(Node<T> link, int i) {
if (link == null)
return 0;
else {
int count = 1;
count += size(link.next, 0);
return count;
}
}
public void printNthNodeFromLast(int n) {
if (empty())
throw new NoSuchElementException("Empty");
Node<T> main_ptr = start;
Node<T> ref_ptr = start;
int count = 0;
while (count < n) {
if (ref_ptr == null) {
System.out.println(n + " is greater than the no of nodes in the list");
return;
}
ref_ptr = ref_ptr.next;
count++;
}
while (ref_ptr != null) {
main_ptr = main_ptr.next;
ref_ptr = ref_ptr.next;
}
System.out.println("Node no " + n + " from the last is " + main_ptr.data);
}
public void display() {
if (empty())
throw new NoSuchElementException("Empty");
display(start);
}
private void display(Node<T> link) {
if (link != null) {
System.out.print(link.data + " ");
display(link.next);
}
}
public boolean empty() {
return start == null;
}
}
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<Integer>();
boolean yes = true;
Scanner scanner = new Scanner(System.in);
do {
System.out.println("\n1. Insert At Start");
System.out.println("2. Insert At End");
System.out.println("3. Insert at Position");
System.out.println("4. Delete");
System.out.println("5. Display");
System.out.println("6. Empty status");
System.out.println("7. Get Size");
System.out.println("8. Get Index of the Item");
System.out.println("9. Replace data at given position");
System.out.println("10. Replace data at given position recusively");
System.out.println("11. Get Middle Element");
System.out.println("12. Get Occurence");
System.out.println("13. Reverse Recusively");
System.out.println("14. Reverse");
System.out.println("15. Swap the nodes");
System.out.println("16. Nth Node from last");
System.out.println("\nEnter your choice");
int choice = scanner.nextInt();
switch (choice) {
case 1:
try {
System.out.println("Enter the item");
linkedList.insertAtStart(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 2:
try {
System.out.println("Enter the item");
linkedList.insertAtEnd(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 3:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
System.out.println("Enter the Item");
linkedList.insertAtPosition(position, scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 4:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
linkedList.delete(position);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 5:
try {
linkedList.display();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 6:
System.out.println(linkedList.empty());
break;
case 7:
try {
System.out.println(linkedList.size());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 8:
try {
System.out.println(linkedList.index(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 9:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
linkedList.replace(position, scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 10:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
System.out.println("Enter the item");
linkedList.replaceRecursively(position, scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 11:
try {
System.out.println(linkedList.middle());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 12:
try {
System.out.println("Enter the item");
System.out.println(linkedList.occurence(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 13:
try {
linkedList.reverseRecusively();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 14:
try {
linkedList.reverse();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 15:
try {
System.out.println("Enter the nodes");
linkedList.swapNode(scanner.nextInt(), scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 16:
try {
System.out.println("Enter which node do you want from last");
linkedList.printNthNodeFromLast(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
default:
System.out.println("Invalid Choice");
break;
}
} while (yes);
scanner.close();
}
}
Consider another possible implementation of a working non-recursive Linked List with generic T placeholder. It works out of the box and the code is a more simple one:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<T> implements Iterable<T> {
private Node first;
private Node last;
private int N;
public LinkedList() {
first = null;
last = null;
N = 0;
}
public void add(T item) {
if (item == null) { throw new NullPointerException("Null object!"); }
if (!isEmpty()) {
Node prev = last;
last = new Node(item, null);
prev.next = last;
}
else {
last = new Node(item, null);
first = last;
}
N++;
}
public boolean remove(T item) {
if (isEmpty()) { throw new IllegalStateException("Empty list!"); }
boolean result = false;
Node prev = first;
Node curr = first;
while (curr.next != null || curr == last) {
if (curr.data.equals(item)) {
// remove the last remaining element
if (N == 1) { first = null; last = null; }
// remove first element
else if (curr.equals(first)) { first = first.next; }
// remove last element
else if (curr.equals(last)) { last = prev; last.next = null; }
// remove element
else { prev.next = curr.next; }
N--;
result = true;
break;
}
prev = curr;
curr = prev.next;
}
return result;
}
public int size() {
return N;
}
public boolean isEmpty() {
return N == 0;
}
private class Node {
private T data;
private Node next;
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
public Iterator<T> iterator() { return new LinkedListIterator(); }
private class LinkedListIterator implements Iterator<T> {
private Node current = first;
public T next() {
if (!hasNext()) { throw new NoSuchElementException(); }
T item = current.data;
current = current.next;
return item;
}
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
}
#Override public String toString() {
StringBuilder s = new StringBuilder();
for (T item : this)
s.append(item + " ");
return s.toString();
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
while(!StdIn.isEmpty()) {
String input = StdIn.readString();
if (input.equals("print")) { StdOut.println(list.toString()); continue; }
if (input.charAt(0) == ('+')) { list.add(input.substring(1)); continue; }
if (input.charAt(0) == ('-')) { list.remove(input.substring(1)); continue; }
break;
}
}
}
For more LinkedList examples, your can check out the article.