In the design and analysis of data structures, a bucket queue is a priority queue for prioritizing elements whose priorities are small integers. It has the form of an array of buckets: an array data structure, indexed by the priorities, whose cells contain buckets of items with the same priority as each other. The bucket queue is the priority-queue analogue of pigeonhole sort, a sorting algorithm that places elements into buckets indexed by their priorities and then concatenates the buckets. Using a bucket queue as the priority queue in a selection sort gives a form of the pigeonhole sort algorithm. Applications of the bucket queue include computation of the degeneracy of a graph as well as fast algorithms for shortest paths and widest paths for graphs with weights that are small integers or are already sorted. Its first use was in a shortest path algorithm by.
This structure can handle the insertions and deletions of elements with integer priorities in the range from 0 to some known bound, as well as operations that find the element with minimum priority. It consists of an array of container data structures, where array cell stores the collection of elements with priority. It can handle the following operations:
To insert an element with priority, add to the container at.
To remove an element with priority, remove from the container at
To find an element with the minimum priority, perform a sequential search to find the first non-empty container, and then choose an arbitrary element from this container.
In this way, insertions and deletions take constant time, while finding the minimum priority element takes time.
Optimizations
As an optimization, the data structure can also maintain an index that lower-bounds the minimum priority of an element. When inserting a new element, should be updated to the minimum of its old value and the new element's priority. When searching for the minimum priority element, the search can start at instead of at zero, and after the search should be left equal to the priority that was found in the search. In this way the time for a search is reduced to the difference between the previous lower bound and its next value; this difference could be significantly smaller than. For applications of monotone priority queues such as Dijkstra's algorithm in which the minimum priorities form a monotonic sequence, the sum of these differences is at most, so the total time for a sequence of operations is, rather than the slower time bound that would result without this optimization. Another optimization can be used to save space when the priorities are monotonic and, at any point in time, fall within a range of values rather than extending over the whole range from 0 to. In this case, one can index the array by the priorities modulo rather than by their actual values. The search for the minimum priority element should always begin at the previous minimum, to avoid priorities that are higher than the minimum but have lower moduli.
Applications
A bucket queue can be used to maintain the vertices of an undirected graph, prioritized by their degrees, and repeatedly find and remove the vertex of minimum degree. This greedy algorithm can be used to calculate the degeneracy of a given graph. It takes linear time, with or without the optimization that maintains a lower bound on the minimum priority, because each vertex is found in time proportional to its degree and the sum of all vertex degrees is linear in the number of edges of the graph. In Dijkstra's algorithm for shortest paths in positively-weighted directed graphs, a bucket queue can be used to obtain a time bound of, where is the number of vertices, is the number of edges, is the diameter of the network, and is the maximum link cost. This variant of Dijkstra's algorithm is also known as Dial's algorithm, after Robert B. Dial, who published it in 1969. In this algorithm, the priorities will only span a range of width, so the modular optimization can be used to reduce the space to. A variant of the same algorithm can be used for the widest path problem, and leads to near-linear-time solutions to the single-source single-destination version of this problem.