Why use two stacks to make a queue? - list

I can see the advantage of using two stacks if an array implementation is used since stacks are more easily implemented using arrays than queues are.
But if linked-lists are used, what is the advantage?
The act of popping the stack onto the queue increases overhead for both linked-list and array implementations.

It's a common way to implement a queue in functional programming languages with purely functional (immutable, but sharing structure) lists (e.g. Clojure, Haskell, Erlang...):
use a pair of lists to represent a queue where elements are in FIFO order in the first list and in LIFO order in the second list
enqueue to the queue by prepending to the second list
dequeue from the queue by taking the first element of the first list
if the first list is empty: reverse the second list and replace the first list with it, and replace the second list with an empty list
(all operations return the new queue object in addition to any possible return values)
The point is that adding (removing) an element to (from) the front of a purely functional list is O(1) and the reverse operation which is O(n) is amortised over all the dequeues, so it's close to O(1), thereby giving you a ~O(1) queue implementation with immutable data structures.

This approach may be used to build a lock-free queue using two atomic single-linked list based stacks, such as provided by Win32: Interlocked Singly Linked Lists.
The algorithm could be as described in liwp's answer, though the repacking step (bullet 4) can be optimized a bit.
Lock-free data structures and algorithms is a very exciting (to some of us) area of programming, but they must be used very carefully. In a general situation, lock-based algorithms are more efficient.

You can make an immutable queue using two immutable stacks.
But, if you just want a mutable queue, using two stacks is a great way to make it slower and more complicated than just using a linked list.

It's a good learning experience, but not a practical one.

Related

Should I use mutable priority queue for dikjstra/A* algorithm?

I am trying to implement A* algorithm and Dikjstra algorithm as a special case of A* (just pass h(x){return 0;} to A*), when choosing the priority_queue, I have two choices
use an empty priority_queue, and push start point when initializing, and do "pop u, push neighbors of u satisfying certain conditions", in this
way, one node might be pushed twice if it is a common neighbor of
two other nodes.
use a mutable priority queue that supports
update()/decreaseKey()/increaseKey(), I could choose data
structures in boost::heap or I could (actually I have) implement a
priority_queue by myself, in this way, all nodes are needed to be pushed to the container when initializing and handles for them need to be kept.
what are the pros and cons of these two strategies and which one is more practical?
A common implementation of a priority queue for Dijkstra's in C++ uses std::set, where the smallest item is set.begin(), and you can find an exact item and erase it. You can also easily define a facade which allows to access std::set with a priority queue-like interface and support the additional update/erase/increaseKey/decreaseKey methods.
Look here for code samples for Dijkstra's implementations with both std::set and std::priority_queue: https://www.topcoder.com/community/data-science/data-science-tutorials/power-up-c-with-the-standard-template-library-part-2/#dijkstra2
This article also makes a claim, that the performance is naturally the same, whether you use std::priority_queue and discard stale items you've popped, or you use std::set and erase the old item immediately.

STL iterable container like priority_queue

I'm new to STL containers (and C++ in general) so thought I would reach out to the community for help. I basically want to have a priority_queue that supports constant iteration. Now, it seems that std::priority_queue doesn't support iteration, so I'm going to have to use something else, but I'm not sure exactly what.
Requirements:
Maintains order on insertion (like a priority queue)
Pop from top of list
Get const access to each element of the list (don't care about the order in the queue for this stage)
One option would be to keep a priority_queue and separately have an unordered_set of references, but I'd rather not have two containers floating around. I could also use a deque and search through for the right insertion position, but I'd rather have the container manage the sorting for me if possible (and constant-time insertion would be nicer than linear-time). Any suggestions?
There are two options that come to mind:
1) Implement your own iterable priority queue, using std::vector and the heap operation algorithms (see Heap Operations here).
2) derive (privately) from priority_queue. This gives you access to the underlying container via data member c. You can then expose iteration, random access, and other methods of interest in your public interface.
Using a std::vector might be enough as others already pointed, but if you want already-ready implementation, maybe use Boost.Heap (which is a library with several priority queue containers): http://www.boost.org/doc/libs/1_53_0/doc/html/heap.html
Boost is a collection of libraries that basically complete the standard library (which is not really big). A lot of C++ developers have boost ready on their dev computer to use it when needed. Just be careful in your choices of libraries.
You can use (ordered) set as a queue. set.begin() will be your top element, and you can pop it via erase(set.begin()).
Have you observed heap (std::make_heap) ? It hasn't order inside of queue, but has priority "pop from top of list" which you need.

Queue-like data structure with random access element removal

Is there a data structure like a queue which also supports removal of elements at arbitrary points? Enqueueing and dequeueing occur most frequently, but mid-queue element removal must be similar in speed terms since there may be periods where that is the most common operation. Consistency of performance is more important than absolute speed. Time is more important than memory. Queue length is small, under 1,000 elements at absolute peak load.In case it's not obvious I'll state it explicitly: random insertion is not required.
Have tagged C++ since that is my implementation language, but I'm not using (and don't want to use) any STL or Boost. Pure C or C++ only (I will convert C solutions to a C++ class.)
Edit: I think what I want is a kind of dictionary that also has a queue interface (or a queue that also has a dictionary interface) so that I can do things like this:
Container.enqueue(myObjPtr1);
MyObj *myObjPtr2 = Container.dequeue();
Container.remove(myObjPtr3);
I think that double-link list is exactly what you want (assuming you do not want a priority queue):
Easy and fast adding elements to both ends
Easy and fast removal of elements from anywhere
You can use std::list container, but (in your case) it is difficult to remove an element
from the middle of the list if you only have a pointer (or reference) to the element (wrapped in STL's list element), but
you do not have an iterator. If using iterators (e.g. storing them) is not an option - then implementing a double linked list (even with element counter) should be pretty easy. If you implement your own list - you can directly operate on pointers to elements (each of them contains pointers to both of its neighbours). If you do not want to use Boost or STL this is probably the best option (and the simplest), and you have control of everything (you can even write your own block allocator for list elements to speed up things).
One option is to use an order statistic tree, an augmented tree structure that supports O(log n) random access to each element, along with O(log n) insertion and deletion at arbitrary points. Internally, the order statistic tree is implemented as a balanced binary search treewith extra information associated with it. As a result, lookups are a slower than in a standard dynamic array, but the insertions are much faster.
Hope this helps!
You can use a combination of a linked list and a hash table. In java it is called a LinkedHashSet.
The idea is simple, have a linked list of elements, and also maintain a hash map of (key,nodes), where node is a pointer to the relevant node in the linked list, and key is the key representing this node.
Note that the basic implementation is a set, and some extra work will be needed to make this data structure allow dupes.
This data structure allows you both O(1) head/tail access, and both O(1) access to any element in the list. [all on average armotorized]

sorted atomic linked list algorithm (priority queue)

Can somebody point me towards an algorithm for a sorted thread-safe atomic (lock-free) linked list/priority queue? I'm aware of how to do just a linked list itself, but now I need one that is sorted. I'm unsure if this is minor change or significant redesign compared to an unsorted list, thus would like to see an existing algorithm before I make my own.
It needn't actually be a list (or technically sorted), but behaves like a priority queue with these properties:
lowest element is the one with the minimum integer field value
access to lowest element in constant time
modification via atomic operations only (no locks)
insertion/removal in linear time
The contents will likely be pointers to structures. The integer field to sort is one of the members of that structure.
This is for a C++ program, but I don't need code examples, an algorithm description is fine. Algorithms which come close, but not perfect, are also appreciated.
Look at this: "Fast and Lock-Free Concurrent Priority Queues for
Multi-Thread Systems". Googling will give you more links for sure.

Is the linked list only of limited use?

I was having a nice look at my STL options today. Then I thought of something.
It seems a linked list (a std::list) is only of limited use. Namely, it only really seems
useful if
The sequential order of elements in my container matters, and
I need to erase or insert elements in the middle.
That is, if I just want a lot of data and don't care about its order, I'm better off using an std::set (a balanced tree) if I want O(log n) lookup or a std::unordered_map (a hash map) if I want O(1) expected lookup or a std::vector (a contiguous array) for better locality of reference, or a std::deque (a double-ended queue) if I need to insert in the front AND back.
OTOH, if the order does matter, I am better off using a std::vector for better locality of reference and less overhead or a std::deque if a lot of resizing needs to occur.
So, am I missing something? Or is a linked list just not that great? With the exception of middle insertion/erasure, why on earth would someone want to use one?
Any sort of insertion/deletion is O(1). Even std::vector isn't O(1) for appends, it approaches O(1) because most of the time it is, but sometimes you are going to have to grow that array.
It's also very good at handling bulk insertion, deletion. If you have 1 million records and want to append 1 million records from another list (concat) it's O(1). Every other structure (assuming stadard/naive implementations) are at least O(n) (where n is the number of elements added).
Order is important very often. When it is, linked lists are good. If you have a growing collection, you have the option of linked lists, array lists (vector in C++) and double-ended queues (deque). Use linked lists if you want to modify (add, delete) elements anywhere in the list often. Use array lists if fast retrieval is important. Use double-ended queues if you want to add stuff to both ends of the data structure and fast retrieval is important. For the deque vs vector question: use vector unless inserting/removing things from the beginning is important, in which case use deque. See here for an in-depth look at this.
If order isn't important, linked lists aren't normally ideal.
std::list is notable for its splice() method, which allows you to move one more more elements from one list to another in constant time, without copying or allocating any elements or list nodes.
This question reminds me of this infamous one. Read it for the parallels as to why such simple data structures are important.
Linked List is a fundamental data structure. Other data structures, like hash maps, may use linked lists internally.
Two different algorithms may have O(1) time complexity, for a look up, but that doesn't mean they have the same performance. For example the first one may be 10 or 100 times faster than the second.
Whenever you need to store, iterate and do something with a bunch of data, the normal (and fast) data stucture for that task is the Linked List. More complex data structures are for special cases, ie Set is suitable when you don't want repeated values.
std::list has the following properties:
Sequence
Front Seuqence
Back Seuqence
Forward Container
Reverse Container
Of these properties std::vector does not have (Back Seuqence)
While std::set does not support any sequence properties or (Reverse Container)
So what does this mean?
Will a back sequence supports O(1) for rend() and rbegin() etc
For full information see:
What are the complexity guarantees of the standard containers?
Linked lists are immutable and recursive datastructures whereas arrays are mutable and imperative (=change-based). In functional programming, there are usually no arrays - You don't change elements but transform lists into new lists. While linked lists don't even need additional memory here, this isn't possible efficiently with arrays.
You can easily build or decompose lists without having to change any value.
double [] = []
double (head:rest) = (2 * head):(double rest)
In C++, which is an imperative language, you won't use lists that often. One example could be a list of spaceships in a game from which you can easily remove all spaceships that have been destroyed since the previous frame.