You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
4.4 KiB
C++

//----------------------------------------------------------------------
// File: pr_queue.h
// Programmer: Sunil Arya and David Mount
// Description: Include file for priority queue and related
// structures.
// Last modified: 01/04/05 (Version 1.0)
//----------------------------------------------------------------------
// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
// David Mount. All Rights Reserved.
//
// This software and related documentation is part of the Approximate
// Nearest Neighbor Library (ANN). This software is provided under
// the provisions of the Lesser GNU Public License (LGPL). See the
// file ../ReadMe.txt for further information.
//
// The University of Maryland (U.M.) and the authors make no
// representations about the suitability or fitness of this software for
// any purpose. It is provided "as is" without express or implied
// warranty.
//----------------------------------------------------------------------
// History:
// Revision 0.1 03/04/98
// Initial release
//----------------------------------------------------------------------
#ifndef PR_QUEUE_H
#define PR_QUEUE_H
#include <ANN/ANNx.h> // all ANN includes
#include <ANN/ANNperf.h> // performance evaluation
//----------------------------------------------------------------------
// Basic types.
//----------------------------------------------------------------------
typedef void *PQinfo; // info field is generic pointer
typedef ANNdist PQkey; // key field is distance
//----------------------------------------------------------------------
// Priority queue
// A priority queue is a list of items, along with associated
// priorities. The basic operations are insert and extract_minimum.
//
// The priority queue is maintained using a standard binary heap.
// (Implementation note: Indexing is performed from [1..max] rather
// than the C standard of [0..max-1]. This simplifies parent/child
// computations.) User information consists of a void pointer,
// and the user is responsible for casting this quantity into whatever
// useful form is desired.
//
// Because the priority queue is so central to the efficiency of
// query processing, all the code is inline.
//----------------------------------------------------------------------
class ANNpr_queue {
struct pq_node { // node in priority queue
PQkey key; // key value
PQinfo info; // info field
};
int n; // number of items in queue
int max_size; // maximum queue size
pq_node *pq; // the priority queue (array of nodes)
public:
ANNpr_queue(int max) // constructor (given max size)
{
n = 0; // initially empty
max_size = max; // maximum number of items
pq = new pq_node[max+1]; // queue is array [1..max] of nodes
}
~ANNpr_queue() // destructor
{ delete [] pq; }
ANNbool empty() // is queue empty?
{ if (n==0) return ANNtrue; else return ANNfalse; }
ANNbool non_empty() // is queue nonempty?
{ if (n==0) return ANNfalse; else return ANNtrue; }
void reset() // make existing queue empty
{ n = 0; }
inline void insert( // insert item (inlined for speed)
PQkey kv, // key value
PQinfo inf) // item info
{
if (++n > max_size) annError("Priority queue overflow.", ANNabort);
register int r = n;
while (r > 1) { // sift up new item
register int p = r/2;
ANN_FLOP(1) // increment floating ops
if (pq[p].key <= kv) // in proper order
break;
pq[r] = pq[p]; // else swap with parent
r = p;
}
pq[r].key = kv; // insert new item at final location
pq[r].info = inf;
}
inline void extr_min( // extract minimum (inlined for speed)
PQkey &kv, // key (returned)
PQinfo &inf) // item info (returned)
{
kv = pq[1].key; // key of min item
inf = pq[1].info; // information of min item
register PQkey kn = pq[n--].key;// last item in queue
register int p = 1; // p points to item out of position
register int r = p<<1; // left child of p
while (r <= n) { // while r is still within the heap
ANN_FLOP(2) // increment floating ops
// set r to smaller child of p
if (r < n && pq[r].key > pq[r+1].key) r++;
if (kn <= pq[r].key) // in proper order
break;
pq[p] = pq[r]; // else swap with child
p = r; // advance pointers
r = p<<1;
}
pq[p] = pq[n+1]; // insert last item in proper place
}
};
#endif