List Manipulation with references - java

So for my assignment we are to implement some referenced based list manipulation methods in a class and then add to a list and demonstrate the methods using a driver file.
I have provided the entire program for download which includes a pdf that explains the assignment. Our professor uploaded a completed driver file and mine is exactly the same as his but I am getting some run-time errors, first is when calling add() for the third time I get a NullPointerException, if I comment out the rest of the add() calls, size() will not return the same size as getSize() and getSizeRecursive().
Please Help me. Link to download: https://www.dropbox.com/s/qe771q3156h9nwx/ListReferenceBased.rar
// ****************************************************
// Reference-based implementation of ADT list.
// ****************************************************
public class ListReferenceBased implements ListInterface {
// reference to linked list of items
private Node head;
private int numItems; // number of items in list
public ListReferenceBased() {
numItems = 0;
head = null;
} // end default constructor
public boolean isEmpty() {
return numItems == 0;
} // end isEmpty
public int size() {
return numItems;
} // end size
private Node find(int index) {
// --------------------------------------------------
// Locates a specified node in a linked list.
// Precondition: index is the array index of the desired node.
// Assumes that 0 <= index < numItems
// Postcondition: Returns a reference to the desired node.
// --------------------------------------------------
Node curr = head;
for (int skip = 0; skip < index; skip++) {
curr = curr.getNext();
} // end for
return curr;
} // end find
public Object get(int index)
throws ListIndexOutOfBoundsException {
if (index >= 0 && index < numItems) {
// get reference to node, then data in node
Node curr = find(index);
Object dataItem = curr.getItem();
return dataItem;
}
else {
throw new ListIndexOutOfBoundsException(
"List index out of bounds on get");
} // end if
} // end get
public void add(int index, Object item)
throws ListIndexOutOfBoundsException {
if (index >= 0 && index <= numItems) {
if (index == 0) {
// insert the new node containing item at
// beginning of list
Node newNode = new Node(item, head);
head = newNode;
}
else {
Node prev = find(index-1);
// insert the new node containing item after
// the node that prev references
Node newNode = new Node(item, prev.getNext());
prev.setNext(newNode);
} // end if
numItems++;
}
else {
throw new ListIndexOutOfBoundsException(
"List index out of bounds on add");
} // end if
} // end add
public void remove(int index)
throws ListIndexOutOfBoundsException {
if (index >= 0 && index < numItems) {
if (index == 0) {
// delete the first node from the list
head = head.getNext();
}
else {
Node prev = find(index-1);
// delete the node after the node that prev
// references, save reference to node
Node curr = prev.getNext();
prev.setNext(curr.getNext());
} // end if
numItems--;
} // end if
else {
throw new ListIndexOutOfBoundsException(
"List index out of bounds on remove");
} // end if
} // end remove
public void removeAll() {
// setting head to null causes list to be
// unreachable and thus marked for garbage
// collection
head = null;
numItems = 0;
} // end removeAll
// TO IMPLEMENT
public String toString(){
Node curr = head;
String str = new String("");
while(curr != null){
str += curr.getItem() + ", ";
curr = curr.getNext();
}
return str;
}
// TO IMPLEMENT
public void reverse(){
Node prev = null;
Node curr = head;
while(curr != null){
Node next = curr.getNext();
curr.setNext(prev);
prev = curr;
curr = next;
}
head = prev;
}
// TO IMPLEMENT
// This is a helper method, so try to define your own method
// that this helper will call.
public void reverseRecursive(){
Node prev = null;
Node curr = head;
reverseRecursiveHelper(prev, curr);
head = prev;
}
public Object reverseRecursiveHelper(Node prev, Node curr){
if(curr == null)
return null;
else {
Node next = curr.getNext();
curr.setNext(prev);
prev = curr;
curr = next;
return reverseRecursiveHelper(prev, curr);
}
}
// TO IMPLEMENT
public int getSize()
// --------------------------------------------------
// Returns the number of items in a linked list.
// Precondition: head points to the first element
// in a list of type node.
// Postcondition: The number of items in the list
// is returned.
// --------------------------------------------------
{
int count = 0;
Node curr = head;
while(curr != null){
curr = curr.getNext();
count++;
}
return count;
}
// TO IMPLEMENT
public int getSize(Node cur)
// --------------------------------------------------
// Returns the number of items in a linked list.
// The initial call should have the beginning of the list
// as it's input argument, i.e. listCount(head);
// Precondition: cur points to a list of type node
// Postcondition: The number of items in the list
// is returned.
// --------------------------------------------------
{
if(cur != null)
return 1 + getSize(cur.getNext());
else //base case
return 0;
}
// TO IMPLEMENT
public int getSizeRecursive()
{
return getSize(head);
}
// TO IMPLEMENT
public Node findMToLast(int m){
Node current = head;
if(current == null)
return null;
for(int i = 0; i < m; i++)
if(current.getNext() != null)
current = current.getNext();
else
return null;
Node mBehind = head;
while (current.getNext() != null){
current = current.getNext();
mBehind = mBehind.getNext();
}
return mBehind;
}
} // end ListReferenceBased
Driver:
// ********************************************************
// Test Reference-based implementation of the ADT list.
// *********************************************************
public class TestListReferenceBased {
static public void main(String[] args)
{
ListReferenceBased aList = new ListReferenceBased();
aList.add(0, new Integer(1));
aList.add(1, new Integer(2));
aList.add(2, new Integer(3));
aList.add(3, new Integer(4));
aList.add(4, new Integer(5));
aList.add(5, new Integer(6));
System.out.println("size() and get(i): ");
for (int i = 0; i < aList.size(); i++)
System.out.println(aList.get(i) + " ");
System.out.println();
System.out.println("Size with size() = " + aList.size());
System.out.println("Size with getSize() = " + aList.getSize());
System.out.println("Size with getSizeRecursive() = " + aList.getSizeRecursive());
System.out.println("Initial List = " + aList);
aList.reverse(); // iterative version
System.out.println("Reverse with reverse() = " + aList);
System.out.println("====================================");
aList.reverseRecursive(); // recursive version
System.out.println("Reverse with reverseRecursive() = " + aList);
int offset = 3;
Node node = aList.findMToLast(offset);
if (node != null)
System.out.println(offset + "-th node to the last node contains " + node.getItem() + ".");
else
System.out.println("Offset(=" + offset + ") to the last node is greater than list size(=" + aList.size() + ").");
} // end main
} // end TestListReferenceBased
Stack trace is:
Exception in thread "main" java.lang.NullPointerException at
ListReferenceBased.add(ListReferenceBased.java:63) at
TestListReferenceBased.main(TestListReferenceBased.java:14)

Related

Deleting a node from the linked list

In this linked list I am trying to delete a node and return the list after deleting the particular node. Here I am not using the Value to delete, I am using the position to delete that particular node. Here in my code the delete function seems to have no effect over the output. What am I doing wrong here?
import java.util.*;
class LinkedList{
Node head;
static class Node{
int data;
Node next;
Node(int d){
this.data = d;
next = null;
}
}
public LinkedList insert(LinkedList l, int data){
Node new_node = new Node(data);
if(l.head == null){
l.head = new_node;
}
else{
Node last = l.head;
while(last.next != null){
last = last.next;
}
last.next = new_node;
}
return l;
}
public LinkedList delete(LinkedList l, int position){
Node current = l.head;
if(position == 0){
current = current.next;
}
int index = 1;
while(index < position - 1){
current = current.next;
index++;
}
current = current.next.next;
Node iterating = l.head;
while(iterating != null){
System.out.print(iterating.data + " ");
iterating = iterating.next;
}
return l;
}
}
public class Main
{
public static void main(String[] args) {
LinkedList l = new LinkedList();
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
int position = sc.nextInt();
for(int i=0; i<number; i++){
int num = sc.nextInt();
l.insert(l,num);
}
l.delete(l,position);
}
}
current=current.next doesn't have any effect on the original LinkedList because with that line of code, you just change where the reference (named as current) points to.
Think about this way,
Node a = new Node()
Node b = new Node()
Node c = new Node()
a.next =b
a = c
These lines of code doesn't result in c being connected to b.
Change code to this:
if (position == 0) return l.head.next;
else {
Node head = l.head;
int index = 1;
Node itr = l.head;
while(index < position) {
itr = itr.next;
index++;
}
if(itr.next != null) itr.next = itr.next.next;
return head;
}
public LinkedList delete(LinkedList l, int position) {
Node previous = null;
Node current = l.head;
int index = 0;
while (current != null && index < position){
previous = current;
current = current.next;
index++;
}
if (current != null) {
if (previous == null) {
l.head = current.next;
} else {
previous.next = current.next;
}
}
System.out.print("[");
Node iterating = l.head;
while (iterating != null) {
System.out.print(iterating.data + ", ");
iterating = iterating.next;
}
System.out.println("]");
return l;
}
The problem in java is that to delete a node either the head must be changed to its next, or the previous node's next must be changed to current's next.
Then too current might become null, have reached the list's end, position > list length.

Initializing linked list

When I run my driver class, my list wont initialize. This is what should be necessary to start the list.
public class SortedListReferenceBased implements ListInterface {
private Node head;
private int numItems; // number of items in list
public SortedListReferenceBased()
// creates an empty list
{
head = new Node(null);
numItems = 0;
} // end default constructor
public boolean isEmpty()
// Determines whether a list is empty
{
return true;
} // end isEmpty
public int size()
// Returns the number of items that are in a list
{
return numItems;
} // end size
public void removeAll()
// Removes all the items in the list
{
head = null;
numItems = 0;
} // end removeAll
public Object get(int index) throws ListIndexOutOfBoundsException
// Retrieves the item at position index of a sorted list, if 0 <= index <
// size().
// The list is left unchanged by this operation.
// Throws an exception when index is out of range.
{
if (index < 0 || index >= numItems) {
throw new ListIndexOutOfBoundsException(index + " is an invalid index");
}
return new Object();
}
public void add(Object item) throws ListException
// Inserts item into its proper position in a sorted list
// Throws an exception if the item connot be placed on the list
{
try {
Node newNode = new Node(item);
if (head != null) {
int i = locateIndexToAdd(item);
if (i >= -1 && i <= numItems) {
add(i, item);
}
} else {
head = new Node(newNode);
Node curr = head.getNext();
curr.setNext(null);
numItems++;
}
} catch (Exception e) {
throw new ListException("Add to List failed: " + e.toString());
}
}
}
The problem seems to be this part of your add method:
head = new Node(newNode);
Node curr = head.getNext();
curr.setNext(null);
numItems++;
I assume the next variable in Node gets initialized with null so head.getNext() returns null for curr. When you then call curr.setNext(null) you get a NullPointerException. Since this add the first entry in your list you want to set the next for your first element to null.
Also you do not have to wrap newNode in a Node since its already a node.
head = newNode;
head.setNext(null);
numItems++;
But since you initialize it with null anyway you don't have to do anything.
head = newNode;
numItems++;

How to reverse a singly-linked list in blocks of some given size in O(n) time in place?

I recently encounter an algorithm problem:
Reverse a singly-linked list in blocks of k in place. An iterative approach is preferred.
The first block of the resulting list should be maximal with regards to k. If the list contains n elements, the last block will either be full or contain n mod k elements.
For example:
k = 2, list = [1,2,3,4,5,6,7,8,9], the reversed list is [8,9,6,7,4,5,2,3,1]
k = 3, list = [1,2,3,4,5,6,7,8,9], the reversed list is [7,8,9,4,5,6,1,2,3]
My code is shown as below.
Is there an O(n) algorithm that doesn't use a stack or extra space?
public static ListNode reverse(ListNode list, int k) {
Stack<ListNode> stack = new Stack<ListNode>();
int listLen = getLen(list);
int firstBlockSize = listLen % k;
ListNode start = list;
if (firstBlockSize != 0) {
start = getBlock(stack, start, firstBlockSize);
}
int numBlock = (listLen) / k;
for (int i = 0; i < numBlock; i++) {
start = getBlock(stack, start, k);
}
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while (!stack.empty()) {
cur.next = stack.peek();
cur = stack.pop();
while (cur.next != null) {
cur = cur.next;
}
}
return dummy.next;
}
public static ListNode getBlock(Stack<ListNode> stack, ListNode start, int blockSize) {
ListNode end = start;
while (blockSize > 1) {
end = end.next;
blockSize--;
}
ListNode temp = end.next;
end.next = null;
stack.push(start);
return temp;
}
public static int getLen(ListNode list) {
ListNode iter = list;
int len = 0;
while (iter != null) {
len++;
iter = iter.next;
}
return len;
}
This can be done in O(n) time using O(1) space as follows:
Reverse the entire list.
Reverse the individual blocks.
Both can be done using something very similar to the standard way to reverse a singly linked-list and the overall process resembles reversing the ordering of words in a string.
Reversing only a given block is fairly easily done by using a length variable.
The complication comes in when we need to move from one block to the next. The way I achieved this was by having the reverse function return both the first and last nodes and having the last node point to the next node in our original linked-list. This is necessary because the last node's next pointer needs to be updated to point to the first node our next reverse call returns (we don't know what it will need to point to before that call completes).
For simplicity's sake, I used a null start node in the code below (otherwise I would've needed to cater for the start node specifically, which would've complicated the code).
class Test
{
static class Node<T>
{
Node next;
T data;
Node(T data) { this.data = data; }
#Override
public String toString() { return data.toString(); }
}
// reverses a linked-list starting at 'start', ending at min(end, len-th element)
// returns {first element, last element} with (last element).next = (len+1)-th element
static <T> Node<T>[] reverse(Node<T> start, int len)
{
Node<T> current = start;
Node<T> prev = null;
while (current != null && len > 0)
{
Node<T> temp = current.next;
current.next = prev;
prev = current;
current = temp;
len--;
}
start.next = current;
return new Node[]{prev, start};
}
static <T> void reverseByBlock(Node<T> start, int k)
{
// reverse the complete list
start.next = reverse(start.next, Integer.MAX_VALUE)[0];
// reverse the individual blocks
Node<T>[] output;
Node<T> current = start;
while (current.next != null)
{
output = reverse(current.next, k);
current.next = output[0];
current = output[1];
}
}
public static void main(String[] args)
{
//Scanner scanner = new Scanner(System.in);
Scanner scanner = new Scanner("3 9 1 2 3 4 5 6 7 8 9\n" +
"2 9 1 2 3 4 5 6 7 8 9");
while (scanner.hasNextInt())
{
int k = scanner.nextInt();
// read the linked-list from console
Node<Integer> start = new Node<>(null);
Node<Integer> current = start;
int n = scanner.nextInt();
System.out.print("Input: ");
for (int i = 1; i <= n; i++)
{
current.next = new Node<>(scanner.nextInt());
current = current.next;
System.out.print(current.data + " ");
}
System.out.println("| k = " + k);
// reverse the list
reverseByBlock(start, k);
// display the list
System.out.print("Result: ");
for (Node<Integer> node = start.next; node != null; node = node.next)
System.out.print(node + " ");
System.out.println();
System.out.println();
}
}
}
This outputs:
Input: 1 2 3 4 5 6 7 8 9 | k = 3
Result: 7 8 9 4 5 6 1 2 3
Input: 1 2 3 4 5 6 7 8 9 | k = 2
Result: 8 9 6 7 4 5 2 3 1
Live demo.
Here is an iterative way of doing it... you read my full explanation here
Node reverseListBlocks1(Node head, int k) {
if (head == null || k <= 1) {
return head;
}
Node newHead = head;
boolean foundNewHead = false;
// moves k nodes through list each loop iteration
Node mover = head;
// used for reversion list block
Node prev = null;
Node curr = head;
Node next = null;
Finish: while (curr != null) {
// move the mover just after the block we are reversing
for (int i = 0; i < k; i++) {
// if there are no more reversals, finish
if (mover == null) {
break Finish;
}
mover = mover.next;
}
// reverse the block and connect its tail to the rest of
// the list (at mover's position)
prev = mover;
while (curr != mover) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
// establish the new head, if we didn't yet
if (!foundNewHead) {
newHead = prev;
foundNewHead = true;
}
// connects previous block's head to the rest of the list
// move the head to the tail of the reversed block
else {
head.next = prev;
for (int i = 0; i < k; i++) {
head = head.next;
}
}
}
return newHead;
}
The easiest way to reverse the single linked list is as follows.
private void reverse(Node node)
{
Node current = Node;
Node prev = null;
Node next = null;
if(node == null || node.next == null)
{
return node;
}
while(current != null)
{
next = current.next;
//swap
current.next = prev;
prev = current;
current = next;
}
node.next = current;
}
This section contains multiple Single Linked List Operation
import java.util.Scanner;
import java.util.Stack;
public class AddDigitPlusLL {
Node head = null;
int len =0;
static class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
public void insertFirst(int data) {
Node newNode = new Node(data);
if (head != null)
newNode.next = head;
head = newNode;
}
public void insertLast(int data) {
Node temp = head;
Node newNode = new Node(data);
if (temp == null)
head = newNode;
else {
Node previousNode = null;
while (temp != null) {
previousNode = temp;
temp = temp.next;
}
previousNode.next = newNode;
}
}
public Long getAllElementValue() {
Long val = 0l;
Node temp=head;
while(temp !=null) {
if(val == 0)
val=(long) temp.data;
else
val=val*10+temp.data;
temp = temp.next;
}
System.out.println("value is :" + val);
return val;
}
public void print(String printType) {
System.out.println("----------- :"+ printType +"----------- ");
Node temp = head;
while (temp != null) {
System.out.println(temp.data + " --> ");
temp = temp.next;
}
}
public void generateList(Long val) {
head = null;
while(val > 0) {
int remaining = (int) (val % 10);
val = val/10;
insertFirst(remaining);
}
}
public void reverseList(Long val) {
head =null;
while(val >0) {
int remaining = (int) (val % 10);
val = val/10;
insertLast(remaining);
}
}
public void lengthRecursive(Node temp) {
if(temp != null) {
len++;
lengthRecursive(temp.next);
}
}
public void reverseUsingStack(Node temp) {
Stack<Integer> stack = new Stack<Integer>();
while(temp != null) {
stack.push(temp.data);
temp = temp.next;
}
head = null;
while(!stack.isEmpty()) {
int val = stack.peek();
insertLast(val);
stack.pop();
}
print(" Reverse Using Stack");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner s = new Scanner(System.in);
AddDigitPlusLL sll = new AddDigitPlusLL();
sll.insertFirst(5);
sll.insertFirst(9);
sll.insertLast(8);
sll.print("List Iterate");
Long val = sll.getAllElementValue();
System.out.println("Enter the digit to add");
Long finalVal = val +s.nextInt();
s.close();
sll.generateList(finalVal);
sll.print("Add int with List Value");
sll.reverseList(finalVal);
sll.print("Reverse the List");
sll.lengthRecursive(sll.head);
System.out.println("Length with Recursive :"+ sll.len);
sll.print("Before call stack reverse method");
sll.reverseUsingStack(sll.head);
}
}

Java count function not working. Console application array of numbers

I am having trouble with my int count(int i) function: The function should count the number of occurrences a number appears in the List. For example there is an array of numbers 3 4 4 1 3 2 1
This is what it should display:
Item 0 count = 0
Item 1 count = 2
Item 2 count = 1
Item 3 count = 2
Item 4 count = 2
Item 5 count = 0
class Bag
{
private Node first; //dummy header node
// Initializes the list to empty creating a dummy header node.
public Bag()
{
first = new Node();
}
// Returns true if the list is empty, false otherwise
public boolean isEmpty()
{
return (first.getNext() == null);
}
// Clears all elements from the list
public void clear()
{
first.setNext(null);
}
// Returns the number of item in the list
public int getLength()
{
int length = 0;
Node current = first.getNext();
while (current != null)
{
length++;
current = current.getNext();
}
return length;
}
// Prints the list elements.
public String toString()
{
String list = "";
Node current = first.getNext();
while (current != null)
{
list += current.getInfo() + " ";
current = current.getNext();
}
return list;
}
// Adds the element x to the beginning of the list.
public void add(int x)
{
Node p = new Node();
p.setInfo(x);
p.setNext(first.getNext());
first.setNext(p);
}
// Deletes an item x from the list. Only the first
// occurrence of the item in the list will be removed.
public void remove(int x)
{
Node old = first.getNext();
Node p = first;
//Finding the reference to the node before the one to be deleted
boolean found = false;
while (old != null && !found)
{
if (old.getInfo() == x)
found = true;
else
{
p = old;
old = p.getNext();
}
}
//if x is in the list, remove it.
if (found)
p.setNext(old.getNext());
}
//public int count(int item) {
// int count = 0;
//for(int i = 0; i < length; i++) {
// if(bag[i] == item) {
// count++;
// }
//}
// return count;
//}
// Inner class Node.
private class Node
{
private int info; //element stored in this node
private Node next; //link to next node
// Initializes this node setting info to 0 and next to null
public Node()
{
info = 0;
next = null;
}
// Sets the value for this node
public void setInfo(int i)
{
info = i;
}
// Sets the link to the next node
public void setNext(Node lnk)
{
next = lnk;
}
// Returns the value in this node
public int getInfo()
{
return info;
}
// Returns the link to the next node
public Node getNext()
{
return next;
}
}
}
// Class implementing a linked list.
class LinkedList
{
private Node first; //dummy header node
// Initializes the list to empty creating a dummy header node.
public LinkedList()
{
first = new Node();
}
// Returns true if the list is empty, false otherwise
public boolean isEmpty()
{
return (first.getNext() == null);
}
// Clears all elements from the list
public void clear()
{
first.setNext(null);
}
// Returns the number of item in the list
public int getLength()
{
int length = 0;
Node current = first.getNext();
while (current != null)
{
length++;
current = current.getNext();
}
return length;
}
// Prints the list elements.
public String toString()
{
String list = "";
Node current = first.getNext();
while (current != null)
{
list += current.getInfo() + " ";
current = current.getNext();
}
return list;
}
// Adds the element x to the beginning of the list.
public void add(int x)
{
Node p = new Node();
p.setInfo(x);
p.setNext(first.getNext());
first.setNext(p);
}
// Deletes an item x from the list. Only the first
// occurrence of the item in the list will be removed.
public void remove(int x)
{
Node old = first.getNext();
Node p = first;
//Finding the reference to the node before the one to be deleted
boolean found = false;
while (old != null && !found)
{
if (old.getInfo() == x)
found = true;
else
{
p = old;
old = p.getNext();
}
}
//if x is in the list, remove it.
if (found)
p.setNext(old.getNext());
}
// Returns the element at a given location in the list
public int get(int location)
{
int item = -1;
int length = getLength();
if (location <1 || location > length)
System.out.println("\nError: Attempted get location out of range.");
else
{
int n = 1;
Node current = first.getNext();
while (n < location)
{
n++;
current = current.getNext();
}
item = current.getInfo();
}
return item;
}
/************************************************************************
Students to complete the following two methods for the LinkedList class
***********************************************************************/
// Adds item to the end of the list
public void addEnd(int item)
{
Node currentPos = new Node();
Node newPos = new Node(); //create a new node
newPos.setInfo(item); //load the data
currentPos = first;
while(currentPos.getNext() !=null)
{
currentPos = currentPos.getNext();
}
currentPos.setNext(newPos);
}
// Replaces the info in the list at location with item
public void replace(int location, int item)
{
Node currentPos = new Node();
Node prevPos = new Node();
Node nextPos = new Node();
int length = getLength();
if (location <1 || location > length)
System.out.println("\nError: Attempted get location out of range.");
else
{
prevPos = first;
for(int i=0; i < location-1; i++)
{
prevPos = prevPos.getNext();
}
currentPos = prevPos.getNext();
nextPos = currentPos.getNext();
Node newPos = new Node();
newPos.setInfo(item);
newPos.setNext(nextPos);
prevPos.setNext(newPos);
}
}
// Inner class Node.
private class Node
{
private int info; //element stored in this node
private Node next; //link to next node
// Initializes this node setting info to 0 and next to null
public Node()
{
info = 0;
next = null;
}
// Sets the value for this node
public void setInfo(int i)
{
info = i;
}
// Sets the link to the next node
public void setNext(Node lnk)
{
next = lnk;
}
// Returns the value in this node
public int getInfo()
{
return info;
}
// Returns the link to the next node
public Node getNext()
{
return next;
}
}
}
public class Lab2B2
{
public static void main(String args[])
{
Bag intBag = new Bag();
for (int i =0; i < 10; i++)
{
int info = (int)(Math.random()*10);
intBag.add(info);
}
// Before List
System.out.print("List creation before: " + intBag);
// Counts the # of occurrences of item in the bag
//System.out.println("\nCount the number of occurrences:");
//for(int i = 0; i <= 10; i++)
//{
//System.out.println("Item " + i + " count = " + list.count(i));
//}
// Returns the number of items in the bag
System.out.print("\nLength of List: " + intBag.getLength());
// Adds an item to the bag
intBag.add(9);
System.out.print("\nList creation - Add(9): " + intBag);
// Removes an item from the bag, all occurrences of item in the bag
intBag.remove(8);
System.out.print("\nList creation - Remove(8): " + intBag);
// Removes all of the items from the bag
intBag.clear();
System.out.print("\nList creation - Clear(): " + intBag);
// Determines whether the bag is empty
}
}
you are managing a LinkedList. what you need to do is run over the nodes and check if any of them equals the item you are checking for. in that case, you increase the count.
the code is full of examples how to traverse the list.
The method getLength() is a very good start as it has code that traverses all the elements. with minor modifications, you get what you want.
public int count(int item) {
int count = 0;
Node current = first.getNext();
while (current != null)
{
if (current.getInfo()==item) {
count++;
}
current = current.getNext();
}
return count;
}
Shouldn't you pass an int[] bag as an argument also, since there is no int[] bag declared as a class member?
public int count(int item, int[] bag) {
int count = 0;
for(int i = 0; i < length; i++) {
if(bag[i] == item) {
count++;
}
}
return count;
}

java list shift items by rearranging links

I'm working with a linked list in java and I need to take a list of x objects and move the odd positioned objects to the end of the list.
I have to do it by using linking, no new nodes, no list.data exchanges.
I feel like I have a decent handle when I'm moving stuff from one list to another, but traversing and appending with references to only one list is really tough.
Here's the actual question ---
Write a method shift that rearranges the elements of a list of integers by moving to the end of the list all values that are in odd-numbered positions and otherwise preserving list order. For example, suppose a variable list stores the following values:
[0, 1, 2, 3, 4, 5, 6, 7]
The call of list.shift(); should rearrange the list to be:
[0, 2, 4, 6, 1, 3, 5, 7]
you must solve this problem by rearranging the links of the list.
below is the class that I need to write the method before (with the aforementioned restrictions.
I can't really come up with a plan of attack.
// 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();
}
// Returns a shorter, more "java.util.LinkedList"-like text representation of the list.
public String toStringShort() {
ListNode.clearCycleData();
String result = "[";
ListNode current = front;
boolean cycle = false;
while (current != null) {
if (result.length() > 1) {
result += ", ";
}
result += current.data;
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += "]";
}
return result;
}
// 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
}
see it this way:
first we need some sort of cursor that will go through the list and point to our "current" node
second we need some boolean variable (i'll call it INV) initialized as FALSE ... everytime we move a node in the list, we invert INV
if you go through the list from the left, the second element is the first to be rearanged, so that will be our initial cursor position
lets take a reference on that element/node, and keep that reference as abort criteria
start of loop:
now remove the current node from the list and insert it at the end of the list (move to the end ... not that the cursor may not move with the node ...)
move the cursor to the node that is right of the former position of the node we just moved (if that exists)
if the current element is our abort criteria (first element we moved) we can assume the list is sorted now in the desired order -> we are finished -> exit the loop ... if it's not our abort criteria ... go on
evaluate "index of the cursor is even" to either TRUE or FALSE ... XOR that with INV
if the result is TRUE move the cursor to the next element ... if it's FALSE remove the node and insert it at the end (move it to the end)
do the loop
--
this approach will not preserve the order while we move through the list, but will have the list in the desired order when it finishes ...
the INV var is for compensation the index shifts when removing a node ... (0,1,2,3 ... if you remove the 1 and put it at the end, 2 will have an odd index, so if we invert that with every move, we get the "right" elements)

Categories

Resources