I am writing a program that will take in a set of data, process it and sort it in a linked list. My issue is that when I look at the output, when my (myList.retrieve(0, 20)); method is called the first time, it prints double what it should. The second time after deleting 2 elements, the output is correct.
public class Lab9Tester {
public static void main(String args[]){
int testData[] = {5, 2, 7, 8, 3, 6, 10, 2, 6};
int numberOfElementsDeleted = 0;
SortedListOfInt myList = new SortedListOfInt();
for (int i = 0; i < testData.length; i++){
myList.addElement(testData[i]);
}
System.out.println("The values in the sorted list are given below");
System.out.println(myList.retrieve(0, 20));
System.out.println("The values in the sorted list between 4 and 7 are given below");
System.out.println(myList.retrieve(4, 7));
numberOfElementsDeleted = myList.deleteElement(6);
System.out.println("Number of deleted elements is " + numberOfElementsDeleted);
System.out.println("The values in the sorted list after deleting all elements with value 6 are given below");
System.out.println(myList.retrieve(0, 20));
}
}
My test program, which when run I expect the ouput:
The values in the sorted list are given below
2 2 3 5 6 6 7 8 10
The values in the sorted list between 4 and 7 are given below
5 6 6 7
Number of deleted elements is 2
The values in the sorted list after deleting all elements with value 6 are given below
2 2 3 5 7 8 10
However the first line of values is printed twice as
2 2 3 5 6 6 7 8 10 2 2 3 5 6 6 7 8 10
My other classes are as follows:
public class SortedListOfInt {
ListGeneral myList = new ListGeneral();
private boolean needToRestart = true;
private boolean restartFlag = false;
public void addElement(int x){
if(myList.listIsEmpty())
{
myList.addAfterCurrent(x);
return;
}
if (myList.endOfList())
{
myList.addBeforeCurrent(x);
myList.restart();
return;
}
if (myList.currentValue() != null){
int currentValue = (int) (myList.currentValue());
if(currentValue >= x)
{
myList.addBeforeCurrent(x);
myList.restart();
}
else if(currentValue < x)
{
myList.getNextNode();
addElement(x);
}
}
}
public String retrieve(int lowerLimit, int upperLimit)
{
if(myList.listIsEmpty())
{
return "";
}
if(myList.endOfList() && needToRestart)
{
myList.restart();
needToRestart = false;
return "" + retrieve(lowerLimit, upperLimit);
}
if(myList.endOfList())
{
needToRestart = true;
return "";
}
int currentValue = (int) (myList.currentValue());
if(currentValue >= lowerLimit && currentValue <= upperLimit)
{
String result =currentValue + " " ;
myList.getNextNode();
return result + retrieve(lowerLimit,upperLimit);
}
else
{
myList.getNextNode();
return retrieve(lowerLimit,upperLimit);
}
}
public int deleteElement(int x)
{
repointToStart();
int currentValue;
if(myList.endOfList())
{
restartFlag = false;
return 0;
}
else
{
currentValue = (int) myList.currentValue();
if(currentValue == x)
{
myList.removeCurrent();
return deleteElement(x) + 1;
}
else
{
myList.getNextNode();
return deleteElement(x);
}
}
}
private void repointToStart()
{
if(restartFlag == false)
{
myList.restart();
restartFlag = true;
}
}
}
Given by the professor:
public class ListGeneral {
protected Node firstNode; // firstNode can be used by this
// class and any of its subclass.
private Node currentNode, previousNode; // These are usable only
// within this class.
public ListGeneral(){ // Constructor creates an
// empty list.
currentNode = null;
firstNode = null;
previousNode = null;
}
/*
* The method addAfterCurrent adds a new node with value x
* after the current node.
*/
public void addAfterCurrent(Object x){
if (firstNode == null){
firstNode = new Node(x, null);
currentNode = firstNode;
}
else{
Node newNode = new Node(x, currentNode.getNext());
currentNode.setNext(newNode);
previousNode = currentNode;
currentNode = newNode;
}
}
/*
* The method addBeforeCurrent adds a new node with value x
* before the current node.
*/
public void addBeforeCurrent(Object x){
if (firstNode == null){
firstNode = new Node(x, null);
currentNode = firstNode;
}
else {
Node newNode = new Node(x, currentNode);
if (previousNode != null) {
previousNode.setNext(newNode);
}
else{
firstNode = newNode;
}
currentNode = newNode;
}
}
/*
* removeCurrent() deletes the current node. This is defined
* only if the list is not empty.
*/
public void removeCurrent(){
Node temp;
if (listIsEmpty() || endOfList()) return;
temp = currentNode.getNext();
/*
* if previousNode is null, firstNode is currentNode.
*/
if (previousNode == null) {
firstNode = temp;
}
else {
previousNode.setNext(temp);
}
currentNode = currentNode.getNext();
}
/*
* listIsEmpty() is true if list is empty.
* current() returns the current node.
* restart() makes the the first node the current node.
*/
public boolean listIsEmpty(){
return firstNode == null;
}
public Object currentValue(){
return currentNode.getValue();
}
public void restart(){
currentNode = firstNode;
previousNode = null;
}
/* endOfList() is true if current is not pointing to
* any node.
*/
public boolean endOfList(){
return currentNode == null;
}
/* getNextNode makes the next node the current node.
* The method returns true if the operation was successful
* otherwise it returns false.
*/
public boolean getNextNode(){
if (currentNode == null) {
return false;
}
else {
previousNode = currentNode;
currentNode = currentNode.getNext();
return true;
}
}
/*
* method toString() returns the result of invoking toString()
* on all successive elements of the list.
*/
public String toString(){
String s = "";
for(restart(); !endOfList(); getNextNode()){
s += currentValue() + "\n";
}
return s;
}
}
As well as given:
public class Node {
private Object value; // self-referential link.
private Node next;
public Node(Object value, Node nextNode) // The constructor inserts the
{ // arguments in the new object.
this.value = value;
this.next = nextNode;
}
public Object getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setValue(Object value){
this.value = value;
}
public void setNext(Node next){
this.next = next;
}
}
The problem is you are setting needToRestart = true in the SortedListofInt class.So when you do the initial retrieve it calls it twice but sets the needToRestart = false. Next time around when you call the retrieve it prints only once. Setting the needToRestart = false initially is working for me and printing out the correct output.
This is working for me
public class SortedListOfInt {
ListGeneral myList = new ListGeneral();
private boolean needToRestart = false;
private boolean restartFlag = false; //the only change
...
}
Related
I have implemented a binary search tree. Most of my test in JUNIT test is going through, including these two. I have implementedleavesIsCorrectWhenTreeIsPerfect() and insertValuesInAscendingOrderIncrementsHeight().
Both of these test goes through, however i do not know if it is correctly written based on what their description is asking.
//EDIT: I have added a test that might be a help to one of the test a need help with.
//TODO: help me understand if I have written the correct code for the test in insertValuesInAscendingOrderIncrementsHeight() and leavesIsCorrectWhenTreeIsPerfect() based on what the description for the test is saying.
Have in mind, that I have not included all the tests in the test class, Because the goes through with my implementation of the tree.
Down here I have included my tree class and the test class with both the test I need help with.
/**
* An Binary Search tree implementation.
* #param <T>
*/
public class Tree <T extends Comparable <T>> implements BSTInterface <T>{
private int size;
private Node root;
public class Node{
private Node Left;
private Node Right;
private T data;
public Node(T data){
this.data = data;
}
public Node getRight(){
return Right;
}
public Node getLeft() {
return Left;
}
public T getData() {
return data;
}
}
public Tree (){
size = 0;
root = null;
}
/**
* Test for presence of a value.
* #param elem
* #return true/false
*/
#Override
public boolean search(T elem) {
if(root == null ||elem == null){
return false;
}
Node node = root;
while(true){
if(node.data.compareTo(elem) > 0){
if(node.Right == null){
return false;
} else{
node = node.Right;
}
} else if(node.data.compareTo(elem) == 0){
break;
} else{
if(node.Left== null){
return false;
}
else{
node = node.Left;
}
}
}
return true;
}
/**
* Add value to tree; duplicates are not allowed.
* Return true if the element is not already present (and is thus inserted),
* false otherwise.
*
* #param elem
* #return true/false
*/
#Override
public boolean insert(T elem) {
if (elem == null){
return false;
}
if (root == null){
root = new Node(elem);
size++;
return true;
}
Node node = root;
while (true){
if (node.data.compareTo(elem) > 0) {
if (node.Right == null){
node.Right = new Node(elem);
size++;
break;
} else {
node = node.Right;
}
} else if (node.data.compareTo(elem) == 0) {
return false;
} else {
if (node.Left == null){
node.Left = new Node(elem);
size++;
break;
} else {
node = node.Left;
}
}
}
return true;
}
/**
* the number of elements in the tree
* #return size.
*/
#Override
public int size() {
return size;
}
/**
* The height of the tree.
* The empty tree and the tree with only the root node both have height 0.
* #return the height of the tree.
*/
#Override
public int height() {
return countHeight(root);
}
/**
* Helper method for height
*/
private int countHeight(Node node){
if(node == null) {
return 0;
}
if (node.Left == null && node.Right == null) {
return 0;
}
return 1 + Math.max(countHeight(node.getLeft()), countHeight(node.getRight()));
}
/**
* The number of leaves in the tree.
* #return the amount of leaves the tree has.
*/
#Override
public int leaves() {
return countLeaves(root);
}
/**
* Helper method for leaves
*/
private int countLeaves(Node node) {
if (node == null) {
return 0;
}
if (node.Left == null && node.Right == null) {
return 1;
}
return countLeaves(node.Left) + countLeaves(node.Right);
}
/**
* A string describing the tree
* #return
*/
public String toString(){
String str = "[" + helpToString(root);
if (str.length() > 1) {
str = str.substring(0, str.length() - 2);
} return str + "]";
}
/**
* Helper method for toString
*/
private String helpToString(Node node) {
String str = "";
if (node != null) {
str += helpToString(node.Right);
str += node.data + ", ";
str += helpToString(node.Left);
}
return str;
}
}
import org.junit.Test;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.Timeout;
import static org.junit.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import java.util.Arrays;
import java.util.stream.IntStream;
/**
* Test class for a tree.
*/
public class TreeTest{
#Rule public Timeout globalTimeout = Timeout.seconds(5);
Tree<Integer> tree;
int[] elementsInTree;
int[] elementsNotInTree;
#Before
public void setUp() {
/**
* This tree should look like this:
*
* 8
* / \
* 3 10
* / \ \
* 1 6 14
* / \ /
* 4 7 13
*/
tree = new Tree<>();
elementsInTree = new int[] {8, 10, 14, 13, 3, 1, 6, 4, 7};
for (int elem : elementsInTree) {
tree.insert(elem);
}
elementsNotInTree = new int[] {34, -3, -10, 12, 74, 5};
}
#Test
public void heightIsLogOfNumLeavesTreeIsPerfect() {
// For a perfect tree, tree.height() == log2(tree.leaves()
// Arrange
Tree<Integer> tree = new Tree<>();
int[] elements = new int[] {8, 3, 10, 1, 6, 9, 14};
int numLeaves = 4;
int logNumLeaves = (int) Math.round(Math.log(numLeaves) / Math.log(2));
for (int elem : elements) {
tree.insert(elem);
}
// Act
int height = tree.height();
// Assert
assertThat(height, equalTo(logNumLeaves));
}
#Test
public void leavesIsCorrectWhenTreeIsPerfect() { //TEST
// A perfect tree has all leaves at the same depth, and all internal nodes
// (i.e. non-leaves) have two children
//
// This test should assert that a perfect tree with 2*n-1 nodes total,
// has exactly n leaves (i.e. that Tree.leaves() returns n).
//
// An example is the perfect three-node tree from the test above:
//
// (1338)
// / \
// (1337) (1396)
// You have to construct your own tree here, with n >= 4
Tree <Integer> tree = new Tree<>();
int n = 4;
for(int i = 0; i>=n; i++) {
tree.insert(i);
int numLeaves = 2*n-1;
int leaves = tree.leaves();
assertThat(leaves,equalTo(numLeaves));
}
}
// Tests for insert/height
#Test
public void insertValuesInAscendingOrderIncrementsHeight() { //TEST
// When inserting elements in ascending order, each element is inserted
// to the right of the deepest node, so the height should increment by
// 1 for each element inserted.
Tree <Integer> tree = new Tree<>();
int val = 100;
for(int i = 0; i < val; i++){
tree.insert(i);
}
int treeHeight = tree.height();
treeHeight++;
assertThat(tree.size(),equalTo(treeHeight));
}
}
for(int i = 0; i>=n; i++) {
tree.insert(i);
The condition of your for loop is always false.
It's awkward that "n" is used in the instructions to describe a tree with n leaves because "n" is traditionally used to describe your node count. But picture a tree with 4 nodes at the bottom, then half that for the prior layer, then half again for the first layer, and you have a tree with 1+2+4 nodes, or 7 nodes total, which coincides with the formula 2*n-1 (2*4-1=7).
#Test
public void leavesIsCorrectWhenTreeIsPerfect() {
int n=4;
int[] balanced=new int[] {4,2,6,1,3,5,7};
for (int i=0; i<balanced.length; i++) {
tree.insert(balanced[i]);
}
int leaves = tree.leaves();
assertThat(balanced.length,equalTo(2*n-1));
assertThat(leaves,equalTo(n));
}
I am creating a program that displays the top ten game scores.
The output displays the game score and a name but in my program the names do not match with the score.
It seems that the numbers get sorted correctly - the names do get sorted with the data. The list sorts from highest to lowest. In the output it shows the highest score is:
23 "stan"
when it should show:
23 "tweak"
public class singlyLinked {
class Node {
int data;
String name;
Node next;
public Node(int data, String name) {
this.data = data;
this.name = name;
this.next = null;
}
public String getName() {
return name;
}
public void setName(String newName) {
this.name = newName;
}
}
public Node head = null;
public Node tail = null;
int size = 0;
public void addNode(int data, String name) {
Node newNode = new Node(data, name);
if (head == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
}
public void sortList() {
Node current = head;
Node index = null;
int temp;
if (head == null) {
return;
} else {
while (current != null) {
index = current.next;
while (index != null) {
if (current.data < index.data) {
temp = current.data;
current.data = index.data;
index.data = temp;
current.getName();
}
index = index.next;
}
current = current.next;
size++;
}
}
}
public void topTen() {
while (size > 10) {
if (head == null) {
return;
} else {
if (head != tail) {
Node current = head;
while (current.next != tail) {
current = current.next;
}
tail = current;
tail.next = null;
} else {
head = tail = null;
}
}
size--;
}
}
public void getSize() {
System.out.println(size);
}
public void display() {
Node current = head;
if (head == null) {
System.out.println("List is empty");
return;
}
while (current != null) {
System.out.println(current.data + current.name + " ");
current = current.next;
}
}
public static void main(String[] args) {
singlyLinked list = new singlyLinked();
System.out.println("HighScore:" + " Name:");
list.addNode(8, " stan");
list.addNode(7, " kenny");
list.addNode(13, " eric");
list.addNode(12, " wendy");
list.addNode(7, " token");
list.addNode(9, " craig");
list.addNode(1, " clyde");
list.addNode(5, " butters");
list.addNode(20, " randy");
list.addNode(1, " sharon");
list.addNode(22, " timmy");
list.addNode(23, " tweak");
list.sortList(); // sorts
list.topTen();
list.display(); // displays
}
}
Is it required to use your own implementation of LinkedList? If not, you can use something like this:
import java.util.Comparator;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<Node> list = new LinkedList<>();
list.add(new Node(8, "stan"));
list.add(new Node(7, "kenny"));
list.add(new Node(13, "eric"));
list.add(new Node(12, "token"));
list.add(new Node(7, "craig"));
list.add(new Node(9, "clyde"));
list.add(new Node(1, "butters"));
list.add(new Node(5, "randy"));
list.add(new Node(20, "sharon"));
list.add(new Node(1, "timmy"));
list.add(new Node(22, "stan"));
list.add(new Node(23, "tweak"));
Collections.sort(list);
for(int i = 0; i < 10; i++){
System.out.println(list.get(i));
}
}
}
class Node implements Comparable<Node>{
String name;
int score;
public Node(int score, String name){
this.score = score;
this.name = name;
}
#Override
public int compareTo(Node another) {
return another.score - this.score;
}
#Override
public String toString() {
return this.name + " : " + this.score;
}
}
So you shouldn't be comparing ints but Nodes.
The standard way of comparing objects in Java is to have them implement Comparable.
class Node implements Comparable<Node> {
// ... your current Node implementation
#Override
public int compareTo(Node that) {
return this.data - that.data;
}
}
Then your sortList should become something like this:
public void sortList() {
Node original = head;
/** Result iteration node. */
Node resultIter = null;
/** The node that is directly before {#code resultIter}. */
Node resultIterPrev = null;
/** A copy of the {#code resultIter} node. */
Node resultIterCopy = null;
/** A temporary node, used for swapping. */
Node temp = null;
if (head == null) {
return;
} else {
// 1. Initialize an empty linked list holding the result.
Node result = null;
// 2.1 Iterate unsorted list
while (original != null) {
// 2.1.1 Scan across the result list to find the location where
// the next element of unsorted list ("original") belongs.
if (result == null) {
result = new Node(original.data, original.name);
} else {
resultIter = result;
boolean added = false;
while (resultIter != null) {
if (original.compareTo(resultIter) > 0) {
resultIterCopy = new Node(resultIter.data, resultIter.name);
temp = resultIter.next;
// Set the value to an existing node so that the pointer
// to "resultIter" remains unchanged
resultIter.data = original.data;
resultIter.name = original.name;
resultIter.next = resultIterCopy;
resultIter.next.next = temp;
added = true;
break;
}
resultIterPrev = resultIter;
resultIter = resultIter.next;
}
// If the next value from the unsorted list belongs at
// the end of the sorted list
if (!added) {
resultIterPrev.next = new Node(original.data, original.name);
}
}
original = original.next;
}
// Swap unsorted list with the sorted one
head = result;
// Find new tail
tail = head;
while (tail.next != null) {
tail = tail.next;
}
}
}
This implementation tries to follow an insertion sort as per described in this answer.
I have extracted size out of your sorting method because it kept increasing every time I invoked sortList. Instead, I've placed it inside addNode:
public void addNode(int data, String name) {
// ... your existing Node adding logic
size++;
}
As you can probably see, creating your own linked list can lead to all sorts of
bugs. Consider using the implementation provided by the Java standard library, as suggested by #LitVitNik.
I am trying to do a Leaderboard for a game by using a Sorted Linked List. I was able to do so by sorting the point in descending order which mean higher point to lower point. Moreover, I will also need to put player name together with the point. The problem comes here. The SLL(Sorted Linked List) I implemented is an Integer data type, it works perfectly with the Integer data type as it sorted the numbers.
SortedListInterface<Integer> Player = new LeaderboardSortedLinkedList<Integer>();
But when I trying to put the player name which used String, it won't be able to do so because the point data type will need to follow the player name's data type.
Below are the codes of the driver class:
public class testLeaderboard {
public static void main(String[] args) {
SortedListInterface<Integer> Player = new LeaderboardSortedLinkedList<Integer>();
Player.add(1000000);
Player.add(500000);
Player.add(250000);
Player.add(125000);
Player.add(64000);
Player.add(32000);
Player.add(16000);
Player.add(8000);
Player.add(4000);
Player.add(2000);
Player.add(1000);
Player.add(500);
Player.add(300);
Player.add(200);
Player.add(100);
System.out.printf("=================================\n"
+ " Leaderboard\n"
+"=================================\n");
for(int i=0; i< Player.size();i++){
System.out.printf("%3d. %s\n",(i+1), Player.get(i+1));
}
}
}
Here is the Entity class
public class Player {
private String name;
private int prize;
public Player(String name, int prize) {
this.name = name;
this.prize = prize;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrize() {
return prize;
}
public void setPrize(int prize) {
this.prize = prize;
}
#Override
public String toString() {
return "Player{" + "name=" + name + ", prize=" + prize + '}';
}
}
Here's the custom Sorted Lineked List
public class LeaderboardSortedLinkedList<T extends Comparable<T>> implements SortedListInterface<T> {
private Node firstNode;
private int length;
public LeaderboardSortedLinkedList() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry);
Node nodeBefore = null;
Node currentNode = firstNode;
while (currentNode != null && newEntry.compareTo(currentNode.data) < 0) {
nodeBefore = currentNode;
currentNode = currentNode.next;
}
if (isEmpty() || (nodeBefore == null)) { // CASE 1: add at beginning
newNode.next = firstNode;
firstNode = newNode;
} else { // CASE 2: add in the middle or at the end, i.e. after nodeBefore
newNode.next = currentNode;
nodeBefore.next = newNode;
}
length++;
return true;
}
public boolean contains(T anEntry) {
boolean found = false;
Node tempNode = firstNode;
int pos = 1;
while (!found && (tempNode != null)) {
if (anEntry.compareTo(tempNode.data) <= 0) {
found = true;
} else {
tempNode = tempNode.next;
pos++;
}
}
if (tempNode != null && tempNode.data.equals(anEntry)) {
return true;
} else {
return false;
}
}
public int size(){
int count = 0;
//Node current will point to head
Node current = firstNode;
while(current != null) {
//Increment the count by 1 for each node
count++;
current = current.next;
}
return count;
}
public T get(int position){
T result = null;
if ((position >= 1) && (position <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < position - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public final void clear() {
firstNode = null;
length = 0;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
return (length == 0);
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data + "\n";;
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
}
And the results is here
=================================
Leaderboard
=================================
1. 1000000
2. 500000
3. 250000
4. 125000
5. 64000
6. 32000
7. 16000
8. 8000
9. 4000
10. 2000
11. 1000
12. 500
13. 300
14. 200
15. 100
Here's my testing on the point with string data type because I can't think a way to use player name and point with 2 different data types at the same time in my custom ADT.
public class testLeaderboard {
public static void main(String[] args) {
SortedListInterface<String> Player = new LeaderboardSortedLinkedList<String>()
Player.add("1000000");
Player.add("500000");
Player.add("250000");
Player.add("125000");
Player.add("64000");
Player.add("32000");
Player.add("16000");
Player.add("8000");
Player.add("4000");
Player.add("2000");
Player.add("1000");
Player.add("500");
Player.add("300");
Player.add("200");
Player.add("100");
System.out.println(Player);
}
And here's the result that it compare the first letter of the string.
8000
64000
500000
500
4000
32000
300
250000
2000
200
16000
125000
1000000
1000
100
Is there anyway to use both String and Integer in one ADT because if i couldn't do so, I won't be able sort the point. I'm so sorry for the long question. I am very new to data structures and algorithms so I really need some help on this. Much appreciate.
To keep the points and names together, you need to add Player objects into the list as they are, not just their points or their names:
SortedListInterface<Player> players = new LeaderboardSortedLinkedList<>();
players.add(new Player("Alpha", 1000000));
players.add(new Player("Beta", 500000));
players.add(new Player("Gamma", 250000));
For this to work, you will need to be able to compare Player objects by their point numbers. You do that by implementing the Comparable interface and adding a compareTo method.
You'll also want to add a toString() method, so that you can print a Player object.
public class Player implements Comparable<Player> {
private String name;
private int prize;
#Override
public int compareTo(Player other) {
return Integer.compare(this.prize, other.prize);
}
#Override
public String toString() {
return String.format("name='%s' prize=%d", name, prize);
}
}
Thank You for helping me I successfully get the output I want. But got a little problem which is this
=================================
Leaderboard
=================================
1. name='Alpha' prize=1000000
2. name='Beta' prize=500000
3. name='Gamma' prize=250000
BUILD SUCCESSFUL (total time: 1 second)
It print the output at this way [name="Alpha"]. Im not sure what is the problem but i guess it's my System.out.print code.
System.out.printf("%3d. %s\n",(i+1), players.get(i+1));
and here's my .get() function.
public T get(int position){
T result = null;
if ((position >= 1) && (position <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < position - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
This question already has answers here:
Reversing a linked list in Java, recursively
(33 answers)
Closed 6 years ago.
I am trying to achieve a reversed link list. The new fresh list must be created recursively.
I am creating the first node in the reversed list and I am trying to create a sublist Next which has the next element as next.next and finally to assign this sublist as next to the node. The issue is that the next node remains NIL although I recreated it in the for loop.
Edit:
The function must not change (add arguments) because some tests are running upon it.
class Node {
private Object item;
private Node next,current;
public Node(Object o, Node n) {
this.item = o;
this.next = n;
}
public Node(Node n) {
}
public static final Node NIL = new Node(Node.NIL, Node.NIL);
public Object getItem() {
return this.item;
}
public Node getNext() {
return this.next;
}
public void setItem(Object o) {
this.item = o;
}
public void setNext(Node n) {
this.next = n;
}
// this method returns the item with index number i
public Object nthItem(int i) {
Node p = this;
while (p!=null){
for (int k=1;k<=i;k++){
p=p.next;
}
return p.item;
}
return null;
}
// this method returns the the next item of the node
public Node nthNext(int i) {
Node p = this;
while (p!=null){
for (int k=1;k<=i;k++){
p=p.next;
}
return p.getNext();
}
return null;
}
public Node nthNode(int i) {
Node p = this;
while (p!=null){
for (int k=1;k<=i;k++){
p=p.next;
}
return p;
}
return NIL;
}
public int length(){
if (this == NIL) return 0;
else return 1 + next.length();
}
public Node remove(Object o){
Node p = this;
if (p == NIL) return NIL;
else if(p.item == o) {
p = p.next;
return p.remove(o);
}
else return new Node(p.item, p.next.remove(o));
}
public Node reverse() {
int i = this.length()-1;
if(this == NIL) return NIL;
Node node = new Node(Node.NIL, Node.NIL);
Node next = NIL;
//create the first node in the reversed list
if(i >= 1) node = new Node(nthItem(i), next);
else node = new Node(nthItem(i), Node.NIL);
//iterate through the original list and create a next node
if (i>0) {
for (int k=i; k>=0; k--){
if (k<=0) {
next = NIL;
}
else {
next = new Node(nthItem(k-1),next);
}
}
}
//debugging in console
System.out.println("final node = " + next.item+" ");
return node;
}
}
class Test{
public static void main(String[] string){
Node n = new Node(1, Node.NIL);
Node nn = new Node(2, n);
Node r = nn.reverse();
System.out.println("\t item " + r.getItem()+ " " + r.getNext().getItem() + " length " + r.length());
}
}
This is a question designed to test whether you understand the implicit stack.
Each time you make a recursive call, you add a stack frame, so consider the stack as if you were performing the routine iteratively.
To reverse the list:
Stack all elements in order
Make a new list by popping each element.
Now convert this to a recursive call
//in [1,2,3,null]
Node reverse(Node n){
//base case
if(n == null)
{
return null;
}
// returns [null,3,2,1]
Node next = reverse(n.getNext());
next.setNext(n);// set the next nodes next to its previous(n on unwinding)
return n;
}
Note that the reverse method here doesn't return the new head, to get the head of the reversed list do the following, maybe making a the above a helper instead.
Node oldHead = n;
Node newHead = tail(n);
oldHead.reverse();
I am doing some exercises on practice-it website. And there is a problem that I don't understand why I didn't pass
Write a method deleteBack that deletes the last value (the value at the back of the list) and returns the deleted value. If the list is empty, your method should throw a NoSuchElementException.
Assume that you are adding this method to the LinkedIntList class as defined below:
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
My work so far is this:
public int deleteBack(){
if(front==null){
throw new NoSuchElementException();
}else{
ListNode current = front;
while(current!=null){
current = current.next;
}
int i = current.data;
current = null;
return i;
}
}
Don't you want to iterate until the current.next is != null?
What you have now passes the entire list, and your last statements do nothing, since current is null already.
Think about the logic you have here
while(current!=null){
current = current.next;
}
When that loop exits, current == null, and then you try to access current's data. Does this point you in the right direction?
// This is the quick and dirty
//By Shewan
public int deleteBack(){
if(size()== 0){ throw new NoSuchElementException(); }
if(front==null){ throw new NoSuchElementException();
}else{
if(front.next == null){
int i = front.data;
front = null;
return i;
}
ListNode current = front.next;
ListNode prev= front;
while(current.next!=null){
prev = current;
current = current.next;
}
int i = current.data;
prev.next = null;
return i;
}
}