I'm new to the data structures and recursion concept. I'm struggling to understand why and who he was able to use the recursion in this concept. I found this code in the forums for this and I couldn't really understand the concept of this. For simple case of 2 1 3 4, if any one can explain the iteration steps, it will be greatly appreciated on my behalf.
Here is the link for hacker rank:
https://www.hackerrank.com/challenges/insert-a-node-into-a-sorted-doubly-linked-list
Node SortedInsert(Node head,int data) {
Node n = new Node();
n.data = data;
if (head == null) {
return n;
}
else if (data <= head.data) {
n.next = head;
head.prev = n;
return n;
}
else {
Node rest = SortedInsert(head.next, data);
head.next = rest;
rest.prev = head;
return head;
}
}
Recursion:
Recursion means a function calls itself. It is used as a simple way to save state information for algorithms that require saving of multiple states, usually a large number of states, and retrieving them in reverse order. (There are alternative techniques that are more professional and less prone to memory issues, such as using a Stack object to save program state).
This example is poor but typical of intro to recursion. Yes, you can iterate through a linked list using recursion but there is absolutely no reason to. A loop would be more appropriate. This is purely for demonstrating how recursion works. So, to answer your question "Why?" it is simply so you can learn the concept and use it later in other algorithms that it actually makes sense.
Recursion is useful when instead of a linked list you have a tree, where each node points to multiple other nodes. In that case, you need to save your state (which node you are on, and which subnode you called last) so that you can traversing one of the linked nodes, then return and go to the next node.
You also asked "how". When a function calls itself, all of its variables are saved (on the program stack) and new ones are created for the next iteration of itself. Then, when that call returns, it goes back to where it was called from and the previous set of variables are loaded. This is very different from a "jump" or a loop of some kind, where the same copies of the variables are used each time. By using recursion, there is a new copy of every local variable each time it is called. This is true even of the "data" variable in the example, which never changes (hence, one inefficiency).
Related
I have two sorted linked list l1 and l2. I wanted to merge l2 into l1 while keeping l1 sorted. My return statement is l1 sorted and l2 is an empty list. How do I approach this problem by using insert_before, insert_after, and remove_node function? Any ideas?
If you know how linked lists are implemented, you can easily just iterate through both of them, using something like the approach below. If you don't know too much about linked lists you might want to read up on those first.
if(l1 == null || l2 == null){
return l1==null ? l2 : l1;
indexA = indexB = 0;
elemA = l1.get(0);
elemB = l2.get(0);
while(indexA<l1.size() || indexB<l2.size()){
if(indexA==l1.size()){
l1.insert_after(l1.size()-1,elemB);
indexA++;
indexB++;
if(indexB<l2.size()){
elemB = l2.get(indexB);
}
continue;
}
if(indexB==l2.size()){
break;
}
if(elemA<elemB){
indexA++;
if(indexA<l1.size()){
elemA = l1.get(indexA);
}
continue;
}
if(elemA>elemB){
l1.insert_before(indexA,elemB);
indexA++;
indexB++;
if(indexB<l2.size()){
elemB = l2.get(indexB);
}
}
return l1;
this is a somehow java like implementation, it iterates through both lists and merges them together on the go. I decided to only return l1 as the empty list would be somewhat useless right?, all the inefficient get() calls could be avoided by writing an own simple LinkedList class to gain access to the next and last fields, which would greatly facilitate navigation.
If you could provide additional information about the methods you have available or the language this has to be written in I could probably provide you with better explanations.
Edit: Explanation
first both elemA /elemB are given the value of the first element in the linked lists then the while loop is used to iterate through them until the index values that are used to keep track of where we are in the lists are both too high (e.g. ==size of list)
Now the first two if statements are to check wheter one of the lists is already completely iterated through, if this is the case for the first list, the next element of the second list is just added behind the last element of l1, as it must be greater than it, otherwise indexA would not have been increased. (In this if statement indexA is also incremented because the size of the list is getting bigger and indexA is compared to l1.size() ), finally the continue statement skips to the next iteration of the loop.
The second if statement in the while loop tests if the second list has already completely been iterated through, if this is true there is nothing more to merge so the loop is stopped by the break statement.
below that is more or less classic mergesort;
if the current element of l1 is smaller than the current element of l2, just go to the next element of l1 and go to next iteration of loop, otherwise insert the current element of l2 before elemA and iterate further here indexA is also incremented because otherwise it would not point to the right element anymore as an element was inserted before it.
is this sufficient?
Edit: Added testing if either of the lists is null as suggested by #itwasntme
The functions insert_before, insert_after, and remove_node are not clearly defined in the question. So assuming one of the parameters is a reference to the "list", is the other parameter an index, an iterator, or a pointer to a node? If the lists are doubly linked lists, then it makes sense for the second parameter to be an iterator or a pointer to a node (each node has a pointer to previous node, so there's no need to scan according to an index to find the prior node).
In the case of Visual Studio's std::list::sort, it uses iterators and std::list::splice to move nodes within a list, using iterators to track the beginning and ending of sub-lists during a merge sort. The version of std::list::splice used by std::list::sort combines remove_node and insert_before into a single function.
I have the following pseudo-code:
function X(data, limit, level = 0)
{
result = [];
foreach (Y(data, level) as entity) {
if (level < limit) {
result = result + X(entity, limit, level + 1);
} else {
//trivial recursion case:
result = result + Z(entity);
}
}
return result;
}
which I need to turn into a plain (e.g. without recursive calls). So far I'm out of ideas regarding how to do that elegantly. Following this answer I see that I must construct the entire stack frames which are basically the code repetitions (i.e. I will place same code again and again with different return addresses).
Or I tried stuff like these suggestions - where there is a phrase
Find a recursive call that’s not a tail call.
Identify what work is being done between that call and its return statement.
But I do not understand how can the "work" be identified in the case when it is happening from within internal loop.
So, my problem is that all examples above are providing cases when the "work can be easily identified" because there are no control instructions from within the function. I understand the concept behind recursion on a compilation level, but what I want to avoid is code repetition. So,
My question: how to approach transformation of the pseudo-code above which does not mean code repetitions for simulating stack frames?
It looks like an algorithm to descend a nested data structure (lists of lists) and flatten it out into a single list. It would have been good to have a simple description like that in the question.
To do that, you need to keep track of multiple indices / iterators / cursors, one at each level that you've descended through. A recursive implementation does that by using the call stack. A non-recursive implementation will need a manually-implemented stack data structure where you can push/pop stuff.
Since you don't have to save context (registers) and a return address on the call stack, just the actual iterator (e.g. array index), this can be a lot more space efficient.
When you're looping over the result of Y and need to call X or Z, push the current state onto the stack. Branch back to the beginning of the foreach, and call Y on the new entity. When you get to the end of a loop, pop the old state if there is any, and pick up in the middle of that loop.
I have my function that needs changing to iteration, because of very slow executing of it.
There are two recursive calls, depends which condition is true.
It's something like this:
(I have static array of classes outside function, let's say data)
void func(int a, int b, int c, int d) {
//something
//non-recursive
//here..
for (i=0; i<data.length; i++) {
if (!data[i].x) {
data[i].x = 1;
if (a == data[i].value1)
func(data[i].value2,b,c,d);
else if (a == data[i].value2)
func(data[i].value1,b,c,d);
data[i].x = 0;
}
}
}
!!
EDIT: Here is my algorithm: http://pastebin.com/F7UfzfHv
Function searches for every paths from one point to another in graph, but returns (to an array) only one path in which are only unique vertices.
!!
And I know that good way to manage that is to use stack... But I don't know how. Could someone give me a hint about it?
There is a good possibility that your function might be computing the same thing again and again, which in technical terms is called as overlapping sub-problems(if you are familiar with the dynamic programming then you might know). First try to identify whether that is the case or not. Since you haven't told anything about what function do and I can't tell the exact problem.
Also the thing you are talking about using a stack is not of great use since recursion uses a stack internally. Using external stack instead of internal is more error prone is not of great use.
May be it is too easy question but Please share how to reverse any kind of stack?
The right answer may be "don't reverse a stack."
If some constraint means you absolutely have to reverse a stack, your question is already answered. But, I can't help but wonder why you want to reverse a stack -- to me, that means you are using the wrong data structure.
If its all pushes, then the reverse, then all pops; thats a queue.
If pushes, pops, and reverses are mixed in random order, you probably want a data structure that specifically supports those operations... it will be confusing when someone reads "stack" but the structure is really something else.
Not sure about scala, but some languages have a double-ended queue to specifically represent a linear collection with access to the head and tail elements -- that may be exactly what you need. If not, a doubly-linked list will do nicely; or a plain old list will do if an O(n) pop()-equivalent isn't an issue.
If your pop() equivalent operation isn't aware of which end to get an element from (e.g., one piece of code is calling reverse, and some other code just says "give me an element" and isn't aware of whether or not reverse has been called), encapsulate the queue with a flag for direction as follows. This will give you the same functionality without having to actually reverse anything.
(sorry for the very-pseudo code, scala isn't in my toolbox).
ReversableStack {
DoublyLinkedList backingStore;
Boolean forward;
get() {
if (forward) return backingStore.take_head();
else return backingStore.take_tail();
}
put(item) {
if (forward) backingStore.add_head(item);
else backingStore.add_tail(item);
}
reverse() {
forward = !forward;
}
}
make new stack;
while (old stack not empty)
x = pop(old stack)
push x on new stack
Or call reverse on the stack, but note that that returns a List if applied to a mutable.Stack. It does return a Stack if you use immutable.Stack.
I don't speak Scala, but according to the doc you simply call reverse on the stack.
public void reverse(Stack st) {
int m = (int)st.Pop();
if (st.Count != 1)
reverse(st);
Push(st , m);
}
public void Push(Stack st , int a) {
int m = (int)st.Pop();
if (st.Count != 0)
Push(st , a);
else
st.Push(a);
st.Push(m);
}
Just loop around popping values from it and pushing them into another stack.
I'm having a hell of a time trying to figure this one out. Everywhere I look, I seem to be only running into explanations on how to actually traverse through the list non-recursively (the part I actually understand). Can anyone out there hammer in how exactly I can go through the list initially and find the actual predecessor/successor nodes so I can flag them in the node class? I need to be able to create a simple Binary Search Tree and go through the list and reroute the null links to the predecessor/successor. I've had some luck with a solution somewhat like the following:
thread(node n, node p) {
if (n.left !=null)
thread (n.left, n);
if (n.right !=null) {
thread (n.right, p);
}
n.right = p;
}
From your description, I'll assume you have a node with a structure looking something like:
Node {
left
right
}
... and that you have a binary tree of these set up using the left and right, and that you want to re-assign values to left and right such that it creates a doublely-linked-list from a depth first traversal of the tree.
The root (no pun intended) problem with what you've got so far is that the "node p" (short for previous?) that is passed during the traversal needs to be independent of where in the tree you currently are - it always needs to contain the previously visited node. To do that, each time thread is run it needs to reference the same "previous" variable. I've done some Python-ish pseudo code with one C-ism - if you're not familiar, '&' means "reference to" (or "ref" in C#), and '*' means "dereference and give me the object it is pointing to".
Node lastVisited
thread(root, &lastVisisted)
function thread(node, lastVisitedRef)
if (node.left)
thread(node.left, lastVisitedRef)
if (node.right)
thread(node.right, lastVisitedRef)
// visit this node, reassigning left and right
if (*lastVisitedRef)
node.right = *lastVisitedRef
(*lastVisitedRef).left = node
// update reference lastVisited
lastVisitedRef = &node
If you were going to implement this in C, you'd actually need a double pointer to hold the reference, but the idea is the same - you need to persist the location of the "last visited node" during the entire traversal.