Given the head of a linked list and the int to search for as parameters, I need a method that will remove the first occurrence of this number in the list, and return the modified list. however i cannot modify the original list. I know how to remove the node from the list, but im not sure how i would keep the original list intact since this has to be done recursively. below is the method
** initially M is the original list. I dont know that it will still be the same list after calling the method again...?
MyList removeNumber(MyList m, int removee){
The idea is that the resulting structure will be a "Y": a two-headed list (actually a simple graph).
One branch of the Y is the original list. The other is your new list with removed node. The vertical stalk of the Y is what's after the element you remove. It's common to both lists. Here's some ascii art with the Y turned on its side showing a list of 1 to 5 with 3 removed.
new -> 1 -> 2 ------\
v
original -> 1 -> 2 -> 3 -> 4 -> 5 -> null
Thinking recursively is all about defining a problem in terms of a smaller version of itself plus a fixed bit of work. And you need a base case (or maybe several).
A linked list is itself a recursive structure:
A list is either empty or it's an element linked by its "next" reference to a list.
Note this defines a list using a smaller list. The base case is the empty list. The fixed bit is the element.
Read this definition a few times, then see how it translates the code:
class MyList {
int value; // the element at the head of this list
MyList next; // the rest of the list
MyList(int value, MyList next) {
this.value = value;
this.next = next;
}
}
The base case "empty list" is just a null reference. The element removal problem expressed recursively using the same pattern becomes:
A copy of a list with an element removed is either a) the rest of the list following the head in the case that the element to be removed is the head or b) a copy of the current node followed by a copy the rest of the list with the desired element removed.
Here I'm defining a "copy of a list with one element removed" using a smaller version of the same thing. Case a) is the base case. The fixed bit is copying the head when it's not the removee.
Of course there's another base case: if the list is empty, the removee can't be found. That's an error.
Putting this in code:
MyList removeNumber(MyList m, int removee) {
if (m == null) throw new RuntimeException("removee not found");
if (m.value == removee) return m.next;
return new MyList(m.value, removeNumber(m.next, removee));
}
Putting the function to use would look something like this:
MyList originalList = ... // list of 1 to 5.
MyList newListWith3removed = removeNumber(originalList, 3);
System.out.println("Original list:");
for (MyList p : originalList) System.out.println(p.value);
System.out.println("With 3 removed:");
for (MyList p : newListWith3removed) System.out.println(p.value);
The output will look as expected: 1 to 5 in the first list and 1,2,4,5 in the second. I.e. the first list is unchanged.
//This function will always return a new list with 'remove' removed
MyList removeNumber(MyList m, int remove){
//if m is empty List, return an empty list
//if head is not the int to remove, return a New list from
// head concat removeNumber(m.next,remove)
//else return removeNumber(m.next,remove)
}
I think it lacks information. I'm assuming however a very traditional implementation for linked list, for instance:
class MyList {
MyList prev;
MyList next;
int data;
static MyList removeNumber(MyList m,int removee) {
if(m == null) return null; // already empty
if(m.data == removee) { // m already is the node to throw away
if(m.prev != null)// relink
m.prev.next = m.next;
if(m.next != null)// relink
m.next.prev = m.prev;
return m.prev;
}
// if this node isn't the one yet, keep looking for
return removeNumber(m.next,removee);
}
}
There are plenty different ways to do that, but you have to provide more info in order to allow us to point you the correct literature.
Related
I am trying to implement the linkedList class, adding a method reverse(int n) to reverse the linked list. For example, I have a linked list { A -> B -> C -> D -> E). When I call reverse(4), the linked list will become D-->C-->B-->A-->E.
I am trying to avoid using iterator, constructing new node and copying the data value. Does anyone have idea how to do it? I know there was a post about reversing linked list but that one is reversing the entire linked list.
Thank you so much for the help!
Since you don't provide your implementation of the LinkedList, i can only provide the general idea:
The complete list can be reversed by simply swaping the pointers to the previous node and the next node and updating the fields for the last and first node.
void reverse()
node tmp = first
first = last
last = tmp
while(tmp.next != null)
node swap = tmp.next
tmp.next = tmp.previous
tmp.previous = swap
tmp = swap
I'll leave it to you to add the bounds
suppose i want to write a method to remove a particular occurrence in a list.
if the key is not on the list, return the list as it is.
methods that are given and i can use :
boolean isEmpty- true if and only if the list is empty
addFirst - adds a given object to the front of the list
removeFirst - removes an object from the front of the list
boolean isMem - checks if the given object is a member in the list
reverse - reverse the order of the items in the list
one of the codes i have found regarding the question is this code:
public void removeAllOccurrences(Object key){
List ans = new List();
while (!isEmpty()){
Object data = removeFirst();
if (!data.equals(key)){
ans.addFirst(data);
}
}
while(!ans.isEmpty()){
addFirst(ans.removeFirst());
but i didn't get the last part : while the list is not empty, add an item in front of the list, and then remove it.. ?
also, i would suggest the following code, will gladly hear your professional opinion:
List ans = new list();
if (!(isMember(key) )
return new list();
else
while (!ans.isEmpty ) {
Link first = curr.link;
if (!(data.equals(key))
ans.addFirst(data) ;
curr=curr.next;
}
As for the first question: the while block has emptied this list, and the ans object contains the new list, so, at the end, the method drains the ans contents to this list.
Regarding the second code block, the while block will never execute because the ans object has just been created, so ans.isEmpty() will always return true.
I am trying to delete the first occurrence of an item from a linked list using list.first and list.next only. (This is not using Java LinkedList<E>.)
I have written the following code, but it deletes all occurrences instead of just the first one:
private static <T> Cell<T> remove(T n,Cell<T> list)
{
Cell<T> ptr; // pointer
Cell<T> temp=null; // new empty list
for(ptr=list; ptr!=null; ptr=ptr.next) {
if(!ptr.first.equals(n))
temp=new Cell<T>(ptr.first,temp); //I guess this is the problem
}
if(ptr!=null)
ptr=ptr.next;
for(; temp!=null; temp=temp.next)
ptr=new Cell<T>(temp.first,ptr);
return ptr;
}
If n equals 3 and list equals [1,3,4,5,3,2], the result I get is [1,4,5,2], but I want it to be [1,4,5,3,2].
Can someone help me understand what I am doing wrong?
You may have an easier time modifying the original list, rather than creating a new one. You could simply keep a pointer to the head of the list and iterate through the list with a current and a previous pointer. When you find the first cell that contains n, rebind the previous cell's .next to skip over the current cell. That way, you can immediately return the head of the list without continuing to recurse.
Can any one help me converting the following Java Code into Objective-C Code. I knew Objective-C but I am not able to translate this code into objective-C.
This is Java Code.
public MyList RecReverse() { //my attempt at the recursive method
if (head.getNext() == null) {
return this;
}
MyList remainder = new MyList();
remainder.head = head.getNext(); // New list has rest of this list (after head)
ListNode temp = new ListNode(head.getString()); // save the first thing in list
remainder = remainder.RecReverse(); //reverse the things in the new 2nd part list
remainder.end().setNext(temp); // put old head on the end
return remainder;
}
private ListNode end() {
ListNode curr = head;
while (curr.getNext() != null) {
curr = curr.getNext();
}
return curr;
}
Thanks
The code is a poor algorithm for reversing a linked list. You presumably have either converted the rest of the class, or have your own linked list class and are just trying to copy the reversal algorithm. You should really include these details and what you've tried when you ask questions on SO, without them people answering can often only guess and you've failed to show any effort - the latter is important.
While this code strongly suggests a linked list there is no clue in this fragment whether this is a single or double-linked list. The code fragment you supply indicates that you have a MyList class with manages a linked list made up of ListNode objects.
The basic operations on a linked list are typically:
Access/change the value stored in the current node - in your code this is the property head and it is an object reference of type ListNode; which itself appears to hold a string.
Access/change the reference to the remainder ("tail") of the list - in your code the getNext & setNext methods.
The method you show RecReverse is a way to recursively produce a new list which is the reverse of the current list. The algorithm does this by reversing the tail of the list and then appending the head onto the end - using the method end.
If the list is double-linked and/or keeps a reference to the end of the list then the algorithm is ok - the method end does not need to traverse the list in this case. Just write it in Objective-C and add it to your list class.
If the list is single-linked and does not keep a reference to the end of the list then the algorithm is poor and the method end does need to traverse the list. This makes it an O(n^2) algorithm - every step traverses the list.
A better algorithm in this case is to use an accumulating parameter. In pseudo-code this is:
Reverse(l)
if length(l) <= 1
then return l // empty list or list with one element reversed is itself
else return ReverseHelper(l, new empty list)
ReverseHelp(remainder, result)
if remainder is empty
then return result // no more elements left to process
else return ReverseHelp(tail of remainder, add head of remainder to front of result)
Implement that on Objective-C and add it to your linked list class.
HTH
You haven't really given context to what 'MyList' objects are.
But if you are simply attempting to reverse an array using any method possibly you can use the following single line:
NSArray* reversedArray = [[array reverseObjectEnumerator] allObjects];
I have a fully built generic Trie in java. I am trying to traverse through the Trie to obtain all the complete combinations for each path. For example, if the Trie contained chars then it would return all the word combinations. For my purposes, I am trying to put all the nodes for each combination into an array and return them. I am stumped however. I only came up with the traversal that goes through each child (+ subchildren) before going back to the parent/starting node (much like a BST traversal). I am using an ArrayList to hold the children for each node. Sorry if it is a bit confusing. A code sample or pseudo code will be much appreciated. Thanks.
EDIT
By combinations, I mean the following. If I had a Trie<char> that looked like the following:
"null"
/ | \
a i t
/ /|\ \
t f m n o
The combinations that I would want returned would be:
[a, t]
[i, f]
[i, m]
[i, n]
[t, o]
and all these arrays/lists could be in one single ArrayList which is returned at the end.
Do a recursive method to (at least) get all the chars in the tree. Just make sure you initialize the chars as an empty List
Stack startRead(Tree tree) {
// validation check
if (tree == null || !tree.hasChild()) return null;
// create Stack to store the lists
Stack listStack = new Stack();
// for every child
List children = tree.getChildren();
for (Tree child : children) {
// create a list
List childList = new ArrayList();
// store (push) it into stack
listStack.push(childList);
// call the recursive
readIt(child, listStack);
}
return listStack;
}
void readIt(Tree tree, Stack listStack) {
// pick the top list from stack
List current = (List) listStack.pop();
// this is the base; if tree has no child don't call this method again.
if (!tree.hasChild()) {
// if it's leaf add the value to current list
current.add(tree.getValue());
// push it back to stack
listStack.push(current);
} else {
// for every child
List children = tree.getChildren();
for (Tree child : children) {
// IMPORTANT! clone the list (if this fails, clone it yourself)
// clone is called when the tree is branching
List childList = current.clone();
// insert this tree value to list
childList.add(tree.getValue());
// push it back
listStack.push(childList);
// call again
readIt(child, listStack);
}
}
}
with this you will have a return value of a Stack consisting Lists of value for each combination.
Hope this helps. :)