I have been struggling with this question in my data structures textbook. I know how the f and r pointers in circular queue works, however, I am having a bit of a trouble cracking this question in my text book. I would be grateful if someone can please guide me or provide some hints. The question is as follows :
Suppose an initially empty circular queue Q has performed a total of 32 enqueue operations, 6 first operations, and 15 dequeue operations, 5 of which returned null to indicate an empty queue.
given that the size of the cicular queue never exceeded 30, what would be the value of the variable f after all operations have been
performed?
Related
i know how to implement stack using one or two queues, but how about n stacks using only 4 queues?
is it possible at all? if it is would you please explain the algorithm?thank you.
Yes it is.
Assuming you can implement a stack from 2 queues (as your question states), the "4 queues" is now just noise, and if you can implement n stacks using 2 stacks, the answer to your question is yes.
This can be done by pushing to the stack not only the element, but the stack's id as well. When popping, you push elements to the other stack, until you find element from required stack, and then return them back.
This can probably be optimized to avoid pushing all the way back over and over again, but I believe worst case complexity is still linear in the number of elements.
Here is a (very unoptimized) pseudo code.
Pop(stack_number):
element = null
while not head_stack.empty():
if head_stack.peek()[0] == stack_number:
element = head_stack.pop()
break
else:
other_stack.push(head_stack.pop())
while not other_stack.empty():
head_stack.push(other_stack.pop())
return element
Push(stack_number, element):
head_stack.push({stack_number, element})
I am trying to develop the following lock free code (c++11):
int val_max;
std::array<std::atomic<int>, 255> vector;
if (vector[i] > val_max) {
val_max =vector[i];
}
The problem is that when there are many threads (128 threads), the result is not correct, because if for example val_max=1, and three threads ( with vector[i] = 5, 15 and 20) will execute the code in the next line, and it will be a data race..
So, I don't know the best way to solve the problem with the available functions in c++11 (I cannot use mutex, locks), protecting the whole code.
Any suggestions? Thanks in advance!
You need to describe the bigger problem you need to solve, and why you want multiple threads for this.
If you have a lot of data and want to find the maximum, and you want to split that problem, you're doing it wrong. If all threads try to access a shared maximum, not only is it hard to get right, but by the time you have it right, you have fully serialized accesses, thus making the entire thing an exercise in adding complexity and thread overhead to a serial program.
The correct way to make it parallel is to give every thread a chunk of the array to work on (and the array members are not atomics), for which the thread calculates a local maximum, then when all threads are done have one thread find the maximum of the individual results.
Do an atomic fetch of val_max.
If the value fetched is greater than or equal to vector[i], stop, you are done.
Do an atomic compare exchange -- compare val_max to the value you read in step 1 and exchange it for the value of vector[i] if it compares.
If the compare succeeded, stop, you are done.
Go to step 1, you raced with another thread that made forward progress.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I came across this question and thought of asking what is the best possible way to achieve this.
Given a FIFO queue. you can assume that queue contains integers. Every time an insertion or deletion happens, a new version of the queue is created. At any time, you have to print(whole content of the queue) any older version of the queue with minimal time and space complexity.
This is assuming you meant a FIFO queue and not some other kind of queue, like a priority queue.
Store it in an array and keep two pointer variables, one to its head and another to its tail.
For example:
insert 3 2 5 9 - version 1
q = [3 2 5 9]
^ ^
delete, delete - version 2
q = [3 2 5 9]
^ ^
insert 6 3 4 - version 3
q = [3 2 5 9 6 3 4]
^ ^
To print a version, you just need to store two values for each version: where the pointers were. Printing is then linear in the size of the queue at that version.
The vector can grow big, but you have to store every element there ever was in it if you want to be able to print any version.
You can also use a linked list to avoid array resizing if you consider that a problem. Just make sure not to remove a node from memory when deleting.
Your problem is to make the queue a partially persistent data structure.
Partially persistent means that you can query any version, but you only can make updates in the most recent version.
A couple years ago I've given a speech about making any pointer data structure persistent. It was based on "Making data structures persistent" by Driscoll, Sarnak, Sleator and Tarjan.
Clearly, any queue can be implemented as a linked data structure. If you want the simplest practical version, you may be interested in method called "The Fat Node Method" which is described on page 91 in the above PDF.
The idea is to store in every node several pointers to the next elements corresponding to different versions of the queue. Each pointer has assigned a version number called timestamp.
For every insert or delete operation, you update pointers only in nodes touched by the update operation.
For lookup operation in the i-th version of the queue, you simply follow the pointers with the largest timestamp not exceeding i. You can find the pointer to follow using the binary search.
In the given PDF there is also a more complex, but also even more efficient method called "The Node-Copying Method".
There are many possible solutions. Here is one with all operations guaranteed O(log(n)) and normal operations an amortized O(log(log(n)).
Keep an operation counter. Store the items in a skip list (see http://en.wikipedia.org/wiki/Skip_list for a definition of that) based on the order of the insertion operation. When an element is removed, fill in the id of the removal operation. For efficiency of access, keep a pair of pointers to the current head and current tail.
To insert an element, add it to the current tail. To return an element, return it to the current head. To return a past state, search the skip list for the then head, then start walking the list until you read the then tail.
The log(n) operations here are finding the past head, and (very occasionally) inserting a new head that happens to be a high node in the skip list.
Now lets us assume that in a FIFO queue, the head pointer is at the beginning of the array, and then the tail pointer is at the end of the current insertion. Then by storing the current tail position pointer value in a variable which is used as the head pointer position during future insertion and tail position again takes the end of that insertion. This way just by using a single variable and with only insertion taking place, previous versions can be printed from the beginning of the array to the tail pointer.
insert 3 2 1 4
a=[3 2 1 4] --version 1
^ ^
b e
p = e;
insert 5 7 8
a=[3 2 1 4 5 7 8] --version 2
^ ^
b e
here version 1 = position 0 to position p = [3 2 1 4]
p = e;
delete 3
a=[2 1 4 5 7 8] --version 3
^ ^
b e
here version 2 = position 0 to position p =[2 1 4 7 8]
where
b = beginning
e = end
Hence by using a single variable to hold previous version tail position and assuming the beginning position to be always 0 , previous versions can be easily printed.
Imagine the following pseudocode
objects[i], 1 <= i <= n
objects[0] = 0
for i from 1 to n
if(objects[i] - objects[i-1] > constant)
do something
I'd like to know if there's a specific name for the assignment objects[0] = 0.
I know that when values like these are used to stop loops, they are called sentinel values.
In this case, however, I'm using it so that the first object evaluated (objects[1]) will have something to compare against - obviously, objects[0] is not a real object, just sort of a flag. Is it still called a sentinel value? Is there another name for this? Or should I not be doing this at all?
Let me know if I haven't made myself clear and I should try to explain my question in another way.
Cormen et al. writes in Introduction to Algorithms (3rd ed.) on page 238:
A sentinel is a dummy object that allows us to simplify boundary
conditions.
This definition is broad enough to account for your usage (e.g. sentinel values of infinity are used in CLRS to simplify the merge routine of mergesort).
I've always called it a "sentinel" whether at the beginning or the end, and haven't yet been fired for that.
Assuming the tree is balanced, how much stack space will the routine use for a tree of 1,000,000 elements?
void printTree(const Node *node) {
char buffer[1000];
if(node) {
printTree(node->left);
getNodeAsString(node, buffer);
puts(buffer);
printTree(node->right);
}
}
This was one of the algo questions in "The Pragmatic Programmer" where the answer was 21 buffers needed (lg(1m) ~= 20 and with the additional 1 at very top)
But I am thinking that it requires more than 1 buffer at levels lower than top level, due to the 2 calls to itself for left and right node. Is there something I missed?
*Sorry, but this is really not a homework. Don't see this on the booksite's errata.
First the left node call is made, then that call returns (and so its stack is available for re-use), then there's a bit of work, then the right node call is made.
So it's true that there are two buffers at the next level down, but those two buffers are required consecutively, not concurrently. So you only need to count one buffer in the high-water-mark stack usage. What matters is how deep the function recurses, not how many times in total the function is called.
This assuming of course that the code is written in a language similar to C, and that the C implementation uses a stack for automatic variables (I've yet to see one that doesn't), blah blah.
The first call will recurse all the way to the leaf node, then return. Then the second call will start -- but by the time the second call takes place, all activation records from the first call will have been cleared off the stack. IOW, there will only be data from one of those on the stack at any given time.