As everyone knows, a standard queue supports two basic operations: insert and popout. And insert occurs at the tail of the queue, while popout occurs at the head of the queue. Here, I have no idea whether I can keep this queue ordered, like non-decreasing, based on this two operations, or perhaps with some additional help functions to achieve that goal?
You just have to change insert function a little. Every time you insert into the queue you have to find the new element place in the queue it could be achieved with following algorithm:
Use a recursive function and every time check if your new element is greater than the element in the middle of the list, if not, try to insert new element in left side of queue else try to insert in the right side of queue, do it recursively until you find the proper place for the element.
Thin algorithm for insert is O(lg(n)).
For popout you could just do what you are done now, popout the last element.
Related
How would you modify a linked list based queue so that first and last node can be accessed in a constant time regardless of data nodes in queue?
You will keep two pointers/reference variables, one for head of queue and other for tail. When you insert an item, you will set the tail to last inserted item, and when you remove an item, your head will obviously go to next item in queue. Since you have two variables for head and tail, it will be a constant time operation to access them.
This is the general way to create a queue with linked list itself, this will be needed to insert items and remove items from queue, nothing special here.
I'm trying to implement a container with the following characteristics:
The container has a fixed size n.
When an item is inserted into the container, if the item is in the data structure it will be moved to the front of it. If not it will be inserted to the front of the data structure, but the last item at the back of the container will be removed to respect the fixed size n.
Building on for 2, it will be required to check whether an item exists in this container in order to know whether to insert or move an item in the container.
The reasoning behind this container, is to keep frequently accessed items in the container. The cost of inserting a new item into the container is large thus it is in my interest to keep it in the container for as long as it is in demand.
Is there a container/data structure that exists that achieves something similar to what I've described? If not can you provide any advice on how to implement it? I'm using C++ but any examples or pseudocode will be equally appreciated.
Edit:
I suppose what I need is a kind of queue with no duplicate items. The queue needs to be searched to see if an item exists within it, and if so moves it to the front of the queue. A fixed size isn't that difficult to adhere to (just check the size before insertion and if it will go over remove the last item in the queue). Basically this post but not allowing any duplicates in the container, and also fast search capabilities to check if an item is within it.
I'm not following the requirements you gave but this seems like it can be implemented as as a double-ended queue (C++ deque or Java Deque). Each time an element is accessed implies a linear search (can't be avoided), then this element is moved to the front (constant time), and the last element removed (also constant time). This should result that the most frequently accessed elements move to the front of the queue over time, decreasing the real-time cost of a linear search.
A double-ended queue can be implemented as a ring-buffer or as a doubly-linked-list. Since you stated a fixed number of elements, the ring buffer seems like the better option.
However, I can't vouch for the implementations of C++ or Java deque.. you may look at the source code to see if its backed as an array or a linked node structure.
Maybe wrap a priority queue with elements having a last-accessed-time attribute?
You may check Splay Tree. If you do some operation on element X, that element move to root.
I have a collection of 10 messages sorted by number of likes message has. Periodically i update that collection with replacing some of the old messages with new that got more likes in meantime, so that collection again contains 10 messages and is sorted by number of likes.
I have api to insert or remove message from collection relative to existing member message. insert(message_id, relative_to, above_or_bellow) and remove(message_id). I want to minimize number of api calls by optimizing position where I insert new messages so that collection is always sorted and 10 long at the end. (in the process length and order is irrelevant, just at the end of process)
I know i can calculate new collection and then replace just messages that dont match their new position but I believe it can be further optimized and algorithms exist already.
Edit:
Note the word "periodically", meaning messages do not come one by one, but in time interval i collect new messages, sort them, and make new collection which i then publish on site via api. So i do have 2 collections, one is simple array in memory, and other is on site.
Idea is to reuse already inserted messages that should be kept and their order in updated collection to save http api calls. I believe there are existing algorithms i could reuse to transform existing collection into already known resulting collection with minimal number of insert, remove operations.
First remove all messages that are no longer in the top 10 liked messages.
In order to get the most from the existing list, we should now look for the longest subsequence of messages that is ordered by their likes (we can use the algorithm mentioned here using number of likes as value How to determine the longest increasing subsequence using dynamic programming? )
We would then remove all other messages (not in subsequence) and insert the missing ones by their order.
I think you only need to keep one list/vector of messages and keep it sorted at all times and up to date with every new message.
Since this collection will always be sorted and assuming it has random access you could use binary search to find the insertion point i.e. O(log_2^M) where M is your maximum list size e.g. 10. But then when you insert here it anyway requires O(M) to shift the elements. Therefore, I would just use a linked list and iterate it while the message to insert (or update) has less likes than the current one.
A priority queue is used to implement a stack that stores characters.
Push(C) is used to implement Insert(Q,C,K) where K is the appropriate key chosen by the implementation.
Pop is implemented as Delete_Min(Q) ,for a sequence of operations in what order must the keys be chosen , strictly decreasing or strictly increasing ?
Let me begin by saying that priority queue and stack are two completely different data structures with different uses and applications. One can not always be used to implement the other.
Yes, there are instances where a data structure can be defined in terms of another: for example you can create a stack or queue using a linked list (quite trivially actually), however implementing a stack using a priority queue will not always work. Why?
Because a stack is first in last out. The last thing you push on a stack WILL be the first thing to pop out. A stack's sole job is to keep the order of pushed items intact and pop in the reverse order.
A priority queue however, will always give you the minimum (or maximum based on implementation) with a pop. A priority queue will have to -by definition- restructure itself to always maintain the "heap property". This means the original order in which you pushed will not necessarily be preserved.
Now, your question should be phrased as "In what situation will a priority queue and a stack behave the same way?"
You mentioned your priority queue pop() will delete the minimum value from your queue which indicates you have a min-heap at hand. In this scenario the only case where a series of pops from priority queue will resemble those that of a stack, would be when the items were all pushed in non-increasing order. It does not have to be strictly decreasing. (think about pushing all of the same values).
Implementing a queue or a priority queue using two stacks are not hard.
Now the questions are
How about using only ONE stack to implement a priority queue?
How about using only ONE stack to implement a normal queue?
Are they even possible?
p.s. of course you should use constant extra space other than ONE stack if necessary
No, it's not possible using only methods provided through a stack interface (i.e. using only push and pop methods) with constant extra space. [1]
Consider trying to simulate a queue using a stack.
When enqueueing, if we simply push onto the stack, we'll end up with another element we need to do something with to get to the front of the queue for a dequeue. It's easy to see that a bunch of enqueues will make it impossible for the next dequeue to take a constant amount of space, as all these enqueued elements need to be popped to get to the front of the queue. We could also put the enqueued element a constant number of elements from the top of the stack, but this doesn't really help much either - the elements below it will need to be dequeued first, so we run into the same problem. Trying to put the enqueued element further than a constant number of elements from the top of the stack will of course take more than a constant amount of space already.
Now consider a priority queue where each new item has lower priority than all items already in the queue. This is synonymous to a simply queue, which, from the above argument, can't be simulated using a single stack with constant space.
[1]: If the stack was implemented as an array or linked-list, as it typically is, it would of course be possible using the functionality for those, but I'm sure that's not what you're asking.
Say you push n elements onto your stack. Now you want the element at the bottom of it (if you want to implement a queue). You're going to need extra O(n) space to keep your other n-1 elements so you can access the bottom one.
=> Under your constraints and only the stack interface methods, there's no way you're going to implement a queue using a single stack and constant space.
It is impossible to perform the task if you only allow standard stack operations (pop, push), as queueing an item would mean poping all the items from the stack, pushing the new item, and then push back all the items. If you use constant time, you can't pop all the items and keep track of them with O(1) memory.
Let's assume you implement a stack with a two-way linked list and allow a reverse method- meaning you flip the order of the stack (tail of the linked list becomes the tail).
Now, for a regular queue, you can perform:
queue- perform reverse, push the new item, and reverse again.
dequeue- perform pop.
Note once you allow a reverse action, it's not a standard stack anymore.
A priority queue is still impossible impossible to implement even if you allow reverse, as you'll still have to perform various comparisons when queueing or dequeueing, and will still encounter the problem of having no space to store the items you want to compare.
Here's a solution that is technically correct, but almost certainly useless for your purposes.
We use a stack S of queues (regular or priority). We initialise S to hold a single empty queue. For any queue operation, we peek at the top element of S and apply the queue operation to it in place. This way, S will only ever hold a single element.
This uses zero memory outside of the stack, if you take the viewpoint that the stack "owns" the memory of all its elements.