#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