I have a stack implementation that uses an array and i am trying to convert it to an array list. The array is top and arrayList is on bottom. Do these 2 segments of code do the same thing? I also have two segments of a pop method one array and one array list. But for this one i get an error that temp has not been initialized and cannot find symbol temp. Any help is appreciated thanks.
USING ARRAY
public void push(T value)
{
if(size==values.length)
expandCapacity();
values[size] = value;
size++;
}
USING ARRAYLIST
public void push(T value)
{
values.add(value);
size++;
}
USING ARRAY
public T pop()
{
if(isEmpty())
throw new RuntimeException("Attempt to pop from empty stack");
size--;
T temp = values[size];
values[size] = null;
return temp;
}
USING ARRAYLIST
public T pop()
{
T temp;
if(isEmpty())
throw new RuntimeException("Attempt to pop from empty stack");
size--;
values.add(temp);
values.temp = null;
//values[size] = null;
return temp;
}
Your push methods, for both your array and ArrayList versions look correct. Your pop for an array looks good. However, the pop for an ArrayList needs work.
You decrement size, which is good, but you are attempting to add temp (which is uninitialized), which doesn't make sense.
You'll need to call remove, passing the index size, which will return the necessary item that you can return in your pop method.
Related
My teacher has assigned a program where I am to create a linked list of some random numbers. I am to create it from a list and then the second part of the assignment is to reverse it. The actual quote is
Write a Java method called reverseLinkedList() that will generate a
reversed linked-list from the linked-list that you create in problem
1. Your method should accept a linked-list as an input and return another linked list that has the node references in the reversed
order. Please do not print the original list in reverse. The idea is
to manipulate the node references so that the nodes are preserved in
same in order as they were originally created.
The code I have generated so far looks like
import java.util.*;
public class progassignment2
{
public static void main(String args[])
{
List<Integer> myList = new ArrayList<Integer>();
Random ran = new Random();
int ranNum;
for(int x = 0;x<5;x++)
{
ranNum = ran.nextInt(500);
myList.add(x,ranNum);
}
LinkedList<Integer> mylinklist = createLinkedList(myList);
System.out.println(mylinklist);
LinkedList<Integer> mylinklistrev = reverseLinkedList(mylinklist);
}
public static LinkedList createLinkedList(List<Integer> integerList)
{
LinkedList<Integer> linkedlist = new LinkedList<Integer>();
linkedlist.addAll(integerList);
return linkedlist;
}
public static LinkedList reverseLinkedList(LinkedList inputList)
{
for(int y = 0;y < inputList.size();y++)
{
inputList.addLast(inputList.pollFirst());
}
return inputList;
}
}
However I don't think I'm doing the assignment correctly, or that I understand what he is asking of me and unfortunately won't answer any questions and just cites "Read the assignment". Any help is greatly appreciated
What about:
public static LinkedList reverseLinkedList(List<Integer> inputList) {
LinkedList<Integer> reversedLinkedlist = new LinkedList<Integer>(inputList);
Collections.reverse(reversedLinkedlist);
return reversedLinkedlist;
}
Usually, exercises on linked lists do not make use of any built-in Java collection (like ArrayList, LinkedList, etc), but are instead meant to make you build your own collection type.
Your teacher probably wants you to build a very basic element, which would then become the building block of your own collection type: imagine an object where you can store a value and a reference to the following value in the list. In code:
class Node {
private int value;
private Node next;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
Each element points to the next one, and the end of the list is marked by the last node's next element being null.
By using objects like this, you'll be able to define your own linked list, without using any pre-defined Collection offered by Java.
You've surely heard about the stack data structure: by reading all the elements in your linked list and putting them inside a stack, once the list will be over, you're going to fetch the elements inside the stack; creating a linked list in the order of the elements pulled from the stack will solve your problem of inverting the linked list.
The idea is to manipulate the node references so that the nodes are
preserved in same in order as they were originally created.
You should create your own LinkedList. You are not allowed to use common ways of reversing like using recursion, stack ,modifications or any collections interface methods.
here is the link includes LinkedList reversing ways and solution:
class LinkedList {
Node head; // head of list
/* Linked list Node */
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
/* Function to print reverse of linked list */
void printReverse(Node head) {
if (head == null)
return;
// print list of head node
printReverse(head.next);
// After everything else is printed
System.out.print(head.data + " ");
}
/* Inserts a new Node at front of the list. */
public void push(int new_data) {
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
public static void main(String args[]) {
LinkedList llist = new LinkedList();
llist.push(4);
llist.push(3);
llist.push(2);
llist.push(1);
llist.printReverse(llist.head);
}
}
I am trying to implement a linked list in java using arrays as the underlying structure. However, I am not sure how to do insert an element in the array after an element and shift the array down by one
class linkedList{
char data[];
int next;
//constructor
public linkedList(int MAX){
data = new char[MAX];
}
public void insertFirst(char d){
if(data[next]==0){
data[next] = d;
next++;
}
else{
System.out.println("list is full");
}
}
public void insertAfter (char after ,char value){
next=0;
while(data[next] !=after){
next++;
}
char temp = data[next+1];
data[next+1] = value;
}
public void printList(){
for(int i=0;i<data.length;i++){
System.out.print(data[i]);
}
}
}
public class myLinkedList {
public static void main(String args[]) {
linkedList list = new linkedList(9);
list.insertFirst('T');
list.insertFirst('H');
list.insertFirst('L');
list.insertAfter('H', 'z');
list.printList();
}
}
Also would this be considered a linked list?
This is not a linked list. What you have is similar to an ArrayList, in that an array is used as the underlying data structure. A linked list is composed of a series of nodes, with each node linked to the next. The linked list is traversed by calling something like node.next() on the current node until the target or the end of the list is reached.
If you want to insert another element into your list structure after reaching the size limit, you will need to create a new array, copy the contents of the old array over, and insert the new element into the array. You can use System.arraycopy() to perform the copying or to shift items within the array.
I have a problem in which I have to search for the maximum element in a stack. I've created my own stack class and used the following approach:
Node node = top; //created a new node which points to the top of stack
int max = node.data; //max contains the value of the top node
while(node != null) {
if(node.data > max) {
max = node.data;
}
node = node.next;
}
//Print the value of max.
Can anybody suggest a more efficient way to do this?
Maintain two stack :
consist of all Nodes.
always keep Max node at top of it, which makes it easier to get max element every time.
The code goes like this :
import java.util.Stack;
public class StackWithMax extends Stack<Integer> {
Stack<Integer> s2;
public StackWithMax() {
s2 = new Stack<Integer>();
}
public void push(int value){
if (value >= max()) {
s2.push(value);
}
super.push(value);
}
public Integer pop() {
int value = super.pop();
if (value == max()) {
s2.pop();
}
return value;
}
public int max() {
if (s2.isEmpty()) {
return Integer.MIN_VALUE;
} else {
return s2.peek();
}
}
}
If you are fine with using an extra space, we can do getMax() in O(1) time. The idea is to use a PriorityQueue based on a comparator that returns the maximum of two elements. Your PriorityQueue will consist of elements arranged ina sorted way based on your comparator. Anytime you push an element in your stack, you push the maximum element corresponding to that element in the PriorityQueue as well. Lets take an example:
Suppose in your stack you are pushing the element 3. Then in your priorityQueue pQ, you would offer 3. At this time, 3 will be the max element corresponding to 3 in the stack.
Lets insert 5 in stack S. Offer 5 in pQ. Since 5 > 3, order of elements in pQ will be 5 3.
Lets push 4 in S. Offer 4 in pQ as well. pQ will now contain elements: 5 4 3. If you do getMax(), you get head of pQ which takes O(1) time since maximum element is always at top of pQ.
In case of S.pop(), you can remove the corresponding popped element from pQ as well in O(1) time if you store the pQ in the form of LinkedList. Hence, all these operations would take O(1) time really.
Going by same logic, you can also do popMax() too in O(1) time. Just return the head of pQ and delete the corresponding node from Stack as well, which again can be done in O(1) of time.
Here is how the structure of both can be:
public class Node{
int data;
Node next;
Node(int data){
this.data = data;
next = null;
}
}
PriorityQueue<Node> pQ = new PriorityQueue<Node>();
Stack<Node> S = new Stack<Node>();
I am implementing a custom Ordered LinkedList class with a nested Ordered ListNode class. Everything is working fine, but I am trying to expand on it by accessing the elements that are removed.
This is not a requirement, but I am curious how this would work since I can only use the methods I was instructed to create, which are boolean add(), boolean remove(), and clear().
I am also keeping track of each modification, which is incremented with each successful addition, removal, or call to clear(). I can simply create another OrderedLinkedList, and add the removed elements to it, but I feel like I'm adding an unnecessary modification count.
Again, this part is just for fun and not required. I feel this will give me a deeper understanding of creating custom classes.
I'll show the remove and main methods. The remove method signature cannot be changed.
public boolean remove(Comparable obj) {
for(OrderedListNode element = head.next; element != tail; element = element.next) {
if(obj.equals(element.dataItem)) { //if element being removed is at the cursor
OrderedListNode previousNode = element.before;
OrderedListNode nextNode = element.next;
nextNode.before = previousNode; //places next element that's after before to the element after current element [prev -> current -> next]
previousNode.next = nextNode; //places prev of next element to the element before current
element.dataItem = (Comparable)NOT_FOUND; //removed element is now null
modCount++; //another modification
theSize--; //reduce the size by 1
return true; //if remove is successful
}
}
return false; //otherwise, not successful removal
}
Main method:
public static void main(String[] args) {
OrderedLinkedList list = new OrderedLinkedList();
OrderedLinkedList removedList = new OrderedLinkedList();
modCount = 0;
list.add("Dog");
list.add("Bird");
list.add("dog");
list.add("bird");
list.add("Cat");
System.out.println("Before removal of element");
System.out.println(list);
list.remove("Dog");
removedList.add("Dog"); //not what I'm wanting to do
System.out.println("Removed " + removedList);
System.out.println("After removal of element");
System.out.println(list);
System.out.println("Total modifications = " + modCount);
System.out.println();
}
Output:
Before removal of element
Bird, Cat, Dog, bird, dog
Removed Dog //not actually accessing the element originally removed. just printing a new list
After removal of element
Bird, Cat, bird, dog
Total modifications = 7 //unnecessary modification due to additional add
If you just want to store the elements that you have removed without increasing your modification count, you can use ArrayList and put your removed elements into it. This way your modification count will not be impacted.
You can store the removed values by implementing an additional pop method. The return type should be Comparable and when the object to be removed found, store it in a temporary object and return that, instead of returning a boolean true. When the object is not found, simply return null.
If the Comparable object is found which is to be removed, the method will return that object so that you can store it. If not, a null will return so that you can use an if-check for the pop method to get that if remove is successful or not.
Here is a sample method I've just written for you;
Sample Pop Method
public Comparable pop(Comparable obj) {
for (OrderedListNode element = head.next; element != tail; element = element.next) {
Comparable temp = null; // declaration of the temporary object
if (obj.equals(element.dataItem)) { // if element being removed is
// at the cursor
temp = obj; // store obj in temp
OrderedListNode previousNode = element.before;
OrderedListNode nextNode = element.next;
nextNode.before = previousNode; // places next element that's
// after before to the element
// after current element [prev
// -> current -> next]
previousNode.next = nextNode; // places prev of next element to
// the element before current
element.dataItem = (Comparable) NOT_FOUND; // removed element is
// now null
modCount++; // another modification
theSize--; // reduce the size by 1
return temp; // if remove is successful
}
}
return null; // otherwise, not successful removal
}
Test Demo
Your test code should be like this;
public static void main(String[] args) {
OrderedLinkedList list = new OrderedLinkedList();
OrderedLinkedList removedList = new OrderedLinkedList();
modCount = 0;
list.add("Dog");
list.add("Bird");
list.add("dog");
list.add("bird");
list.add("Cat");
System.out.println("Before removal of element");
System.out.println(list);
// list.remove("Dog"); // not needed anymore
// removedList.add("Dog"); //not what I'm wanting to do
// pop returns the removed object
removedList.add(list.pop("Dog"));
System.out.println("Removed " + removedList);
System.out.println("After removal of element");
System.out.println(list);
System.out.println("Total modifications = " + modCount);
System.out.println();
}
I'm using a linked list and I altered the standard remove method because I wanted to return both the removed node which is normal, but also return the node before it so for example if I wanted to change a direct reference i.e a tail node to the previous node I could. I was wondering if using a hashmap to achieve this as shown below is the best way to go about this or if there is a better way to achieve what I want? (Note: the below code works I'm just looking to see if there is a more elegant solution)
public HashMap<String, Node> remove(int i)
{
if(isEmpty()) return null;
else
{
HashMap<String, Node> temp = new HashMap<>();
if(i == 0)
{
temp.put(REMOVE_NODE_KEY, firstNode);
firstNode = (E)firstNode.getNext();
temp.put(REMOVE_NEW_KEY, firstNode);
}
else
{
NodeIterator<E> iterator = new NodeIterator<>(firstNode, i, 1);
Node prev = iterator.getEnd();
temp.put(REMOVE_NODE_KEY, prev.getNext());
prev.setNext(prev.getNext().getNext());
temp.put(REMOVE_NEW_KEY, prev);
}
size--;
return temp;
}
}
Couple you just return an array of Nodes?
temp = Node[2];
temp[0] = prev.getNext();
temp[1] = prev.getNext.getNext();
return temp;
A HashMap is rather heavy for this kind of usage. Really, all you want is some kind of "record" or "struct" with two elements. You could define a simple class:
public class NodeAndNewKey {
public Node nodeKey;
public Node newKey;
public NodeAndNewKey(Node nodeKey, Node newKey) {
this.nodeKey = nodeKey;
this.newKey = newKey;
}
}
public NodeAndNewKey remove(int i) { //etc.
You can probably come up with better names than I did.
Another possibility is to return a 2-element array:
public Node[] remove(int i) { // etc.
and define the [0] element as holding the "node key" and the [1] as holding the "new key", or whatever. I don't like it as much because it's less readable when you use it, but Android libraries do things like this sometimes. You could define constants like public static final int REMOVE_NODE_KEY = 0; public static final int REMOVE_NEW_KEY = 1; to make it more readable when retrieving elements from the result array.