#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Queue/PriQueue.hh"
// This file is part of RAVL, Recognition And Vision Library
// Copyright (C) 2001, University of Surrey
// This code may be redistributed under the terms of the GNU Lesser
// General Public License (LGPL). See the lgpl.licence file for details or
// see http://www.gnu.org/copyleft/lesser.html
// file-header-ends-here
#ifndef PRIQUEUE_HEADER
#define PRIQUEUE_HEADER 1
////////////////////////////////////////////////
//! userlevel=Normal
//! example=TPriQH.cc
//! docentry="Ravl.Core.Queues"
//! rcsid="$Id: PriQueue.hh,v 1.4 2002/07/29 14:27:10 craftit Exp $"
//! file="Ravl/Core/Container/Queue/PriQueue.hh"
//! author="Charles Galambos"
//! date="24/08/98"
//! lib=RavlCore
#include "Ravl/SDArray1d.hh"
#include "Ravl/RCWrap.hh"
#include "Ravl/Tuple2.hh"
#include "Ravl/Assert.hh"
namespace RavlN {
//: Fixed size priority queue.
// Priority queue implemented in a fixed size array.
// BIG OBJECT
//
// Keys must have operation '<' defined.
// This queue assumes: **** Small numbers == High priority. ****
//
template
class PriQueueC {
public:
PriQueueC(UIntT initSize = 32);
//: Default constructor.
PriQueueC(const PriQueueC &body);
//: Copy constructor.
bool IsElm(void) const
{ return Array().Size() > 0; }
//: Does the queue contains any items ?
bool IsEmpty(void) const
{ return Array().Size() == 0; }
//: Is the queue empty ?
D &Top(void);
//: Look/Modify data on top of queue.
// Reference not garanteed to stay valid
// after any insert/delete operation !
const D &Top(void) const;
//: Look at data on top of queue.
// Reference not garanteed to stay valid
// after any insert/delete operation !
const K &TopKey(void) const;
//: Look at key on top of queue.
// Reference not garanteed to stay valid
// after any insert/delete operation !
void DelTop(void);
//: Delete item on top of queue.
// NB. IsElm(), must be true before calling this.
Tuple2C GetTopPair(void);
//: Get Key/Data pair from queue.
D GetTop(void);
//: Get Data from top of queue.
void Insert(const K &Key,const D &Data)
{ Insert(Tuple2C(Key,Data)); }
//: Insert Data/Key into queue.
void Insert(const Tuple2C &dat);
//: Insert Data/Key into queue.
bool Remove(const Tuple2C &New)
{ return false; }
//: Remove all instances of Key from queue.
//!bug: NOT IMPLEMENTED
// Returns True if found.
bool Remove(const K &Key)
{ return false; }
//: Remove all instances of Key from queue.
//!bug: NOT IMPLEMENTED
// Returns True if found.
UIntT Size(void) const
{ return Array().Size(); }
//: Get number of items in queue.
void Empty(void)
{ Array().Empty(); }
//: Empty the queue of all its contents.
bool Check();
//: Check consistancy.
protected:
RCWrapC > > data;
SDArray1dC > &Array()
{ return data.Data(); }
const SDArray1dC > &Array() const
{ return data.Data(); }
};
//////////////////////////////////////////
template
PriQueueC::PriQueueC(UIntT initSize)
: data(SDArray1dC >(initSize))
{}
template
PriQueueC::PriQueueC(const PriQueueC &body)
: data(body.data)
{}
template
D &PriQueueC::Top(void) {
RavlAssert(IsElm());
return Array()[0].Data2();
}
template
const D &
PriQueueC::Top(void) const {
RavlAssert(IsElm());
return Array()[0].Data2();
}
template
const K &
PriQueueC::TopKey(void) const {
RavlAssert(IsElm());
return Array()[0].Data1();
}
template
void PriQueueC::DelTop(void) {
SDArray1dC > &arr = Array();
UIntT child;
const UIntT tsize = arr.Size() - 1;
if(tsize == 0) {
arr.Chop();
return ;
}
Tuple2C lastelem = arr[tsize];
UIntT i;
for(i = 1;i * 2 <= tsize;i = child+1) {
child = (i * 2) - 1;
if((child != tsize) && arr[child+1].Data1() < arr[child].Data1())
child++;
if(arr[child].Data1() < lastelem.Data1())
arr[i-1] = arr[child];
else
break;
}
arr[i-1] = lastelem;
arr.Chop();
}
template
Tuple2C PriQueueC::GetTopPair(void) {
Tuple2C ret = Array()[0];
DelTop();
return ret;
}
template
D PriQueueC::GetTop(void) {
D ret = Array()[0].Data2();
DelTop();
return ret;
}
template
void PriQueueC::Insert(const Tuple2C &dat) {
SDArray1dC > &arr = Array();
UIntT i;
i = arr.Size() + 1;
if(i == 1) { // First in queue ?
arr.Add(dat);
return ;
}
// Need do any shifting at all ?
if(arr[i/2-1].Data1() < dat.Data1()) {
arr.Add(dat); // No, just add on end.
return ;
}
i /= 2;
Tuple2C tmp(arr[i-1]);
// Have to use tempory here as array may be resized and the
// reference returned from arr[] may be invalid.
arr.Add(tmp); // Move up.
for(;(i > 1) && dat.Data1() < arr[i/2-1].Data1();i /= 2)
arr[i-1] = arr[i/2-1];
arr[i-1] = dat;
}
template
bool PriQueueC::Check() {
SDArray1dC > &arr = Array();
for(UIntT i = 1;i < Size();i++) {
RavlAssert(arr[((i+1)/2)-1].Data1() < arr[i].Data1());
}
return true;
}
}
#endif