You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
5.7 KiB
232 lines
5.7 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkPriorityQueue.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkPriorityQueue.h"
|
|
#include "vtkObjectFactory.h"
|
|
|
|
vtkCxxRevisionMacro(vtkPriorityQueue, "$Revision: 1.32 $");
|
|
vtkStandardNewMacro(vtkPriorityQueue);
|
|
|
|
// Instantiate priority queue with default size and extension size of 1000.
|
|
vtkPriorityQueue::vtkPriorityQueue()
|
|
{
|
|
this->Size = 0;
|
|
this->Extend = 1000;
|
|
this->Array = NULL;
|
|
this->MaxId = -1;
|
|
this->ItemLocation = vtkIdTypeArray::New();
|
|
}
|
|
|
|
// Allocate priority queue with specified size and amount to extend
|
|
// queue (if reallocation required).
|
|
void vtkPriorityQueue::Allocate(const vtkIdType sz, const vtkIdType ext)
|
|
{
|
|
this->ItemLocation->Allocate(sz,ext);
|
|
for (vtkIdType i=0; i < sz; i++)
|
|
{
|
|
this->ItemLocation->SetValue(i,-1);
|
|
}
|
|
|
|
this->Size = ( sz > 0 ? sz : 1);
|
|
if ( this->Array != NULL )
|
|
{
|
|
delete [] this->Array;
|
|
}
|
|
this->Array = new vtkPriorityQueue::Item[sz];
|
|
this->Extend = ( ext > 0 ? ext : 1);
|
|
this->MaxId = -1;
|
|
}
|
|
|
|
// Destructor for the vtkPriorityQueue class
|
|
vtkPriorityQueue::~vtkPriorityQueue()
|
|
{
|
|
this->ItemLocation->Delete();
|
|
if ( this->Array )
|
|
{
|
|
delete [] this->Array;
|
|
}
|
|
}
|
|
|
|
// Insert id with priority specified.
|
|
void vtkPriorityQueue::Insert(double priority, vtkIdType id)
|
|
{
|
|
vtkIdType i, idx;
|
|
vtkPriorityQueue::Item temp;
|
|
|
|
// check and make sure item hasn't been inserted before
|
|
if ( id <= this->ItemLocation->GetMaxId() &&
|
|
this->ItemLocation->GetValue(id) != -1 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// start by placing new entry at bottom of tree
|
|
if ( ++this->MaxId >= this->Size )
|
|
{
|
|
this->Resize(this->MaxId + 1);
|
|
}
|
|
this->Array[this->MaxId].priority = priority;
|
|
this->Array[this->MaxId].id = id;
|
|
if ( id >= this->ItemLocation->GetSize() ) //might have to resize and initialize
|
|
{
|
|
vtkIdType oldSize = this->ItemLocation->GetSize();
|
|
this->ItemLocation->InsertValue(id,this->MaxId);
|
|
for (i=oldSize; i < this->ItemLocation->GetSize(); i++)
|
|
{
|
|
this->ItemLocation->SetValue(i, -1);
|
|
}
|
|
this->ItemLocation->SetValue(id,this->MaxId);
|
|
}
|
|
|
|
this->ItemLocation->InsertValue(id,this->MaxId);
|
|
|
|
// now begin percolating towards top of tree
|
|
for ( i=this->MaxId;
|
|
i > 0 && this->Array[i].priority < this->Array[(idx=(i-1)/2)].priority;
|
|
i=idx)
|
|
{
|
|
temp = this->Array[i];
|
|
|
|
this->ItemLocation->SetValue(temp.id,idx);
|
|
this->Array[i] = this->Array[idx];
|
|
|
|
this->ItemLocation->SetValue(this->Array[idx].id,i);
|
|
this->Array[idx] = temp;
|
|
}
|
|
}
|
|
|
|
// Simplified call for easier wrapping for Tcl.
|
|
vtkIdType vtkPriorityQueue::Pop(vtkIdType location)
|
|
{
|
|
double priority;
|
|
return this->Pop(location, priority);
|
|
}
|
|
|
|
// Removes item at specified location from tree; then reorders and
|
|
// balances tree. The location == 0 is the root of the tree.
|
|
vtkIdType vtkPriorityQueue::Pop(vtkIdType location, double &priority)
|
|
{
|
|
vtkIdType id, i, j, idx;
|
|
vtkPriorityQueue::Item temp;
|
|
|
|
if ( this->MaxId < 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
id = this->Array[location].id;
|
|
priority = this->Array[location].priority;
|
|
|
|
// move the last item to the location specified and push into the tree
|
|
this->Array[location].id = this->Array[this->MaxId].id;
|
|
this->Array[location].priority = this->Array[this->MaxId].priority;
|
|
|
|
this->ItemLocation->SetValue(this->Array[location].id,location);
|
|
this->ItemLocation->SetValue(id,-1);
|
|
|
|
if ( --this->MaxId <= 0 )
|
|
{
|
|
return id;
|
|
}
|
|
|
|
// percolate into the tree
|
|
for ( j=0, i=location; i <= (this->MaxId-1)/2; i=j )
|
|
{
|
|
idx = 2*i + 1;
|
|
|
|
if ( this->Array[idx].priority < this->Array[idx+1].priority ||
|
|
idx == this->MaxId )
|
|
{
|
|
j = idx;
|
|
}
|
|
else
|
|
{
|
|
j = idx + 1;
|
|
}
|
|
|
|
if ( this->Array[i].priority > this->Array[j].priority )
|
|
{
|
|
temp = this->Array[i];
|
|
|
|
this->ItemLocation->SetValue(temp.id,j);
|
|
this->Array[i] = this->Array[j];
|
|
|
|
this->ItemLocation->SetValue(this->Array[j].id,i);
|
|
this->Array[j] = temp;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
// Protected method reallocates queue.
|
|
vtkPriorityQueue::Item *vtkPriorityQueue::Resize(const vtkIdType sz)
|
|
{
|
|
vtkPriorityQueue::Item *newArray;
|
|
vtkIdType newSize;
|
|
|
|
if (sz >= this->Size)
|
|
{
|
|
newSize = this->Size + sz;
|
|
}
|
|
else
|
|
{
|
|
newSize = sz;
|
|
}
|
|
|
|
if (newSize <= 0)
|
|
{
|
|
newSize = 1;
|
|
}
|
|
|
|
newArray = new vtkPriorityQueue::Item[newSize];
|
|
|
|
if (this->Array)
|
|
{
|
|
memcpy(newArray, this->Array,
|
|
(sz < this->Size ? sz : this->Size) * sizeof(vtkPriorityQueue::Item));
|
|
delete [] this->Array;
|
|
}
|
|
|
|
this->Size = newSize;
|
|
this->Array = newArray;
|
|
|
|
return this->Array;
|
|
}
|
|
|
|
// Reset all of the entries in the queue so they don not have a priority
|
|
void vtkPriorityQueue::Reset()
|
|
{
|
|
this->MaxId = -1;
|
|
|
|
for (int i=0; i <= this->ItemLocation->GetMaxId(); i++)
|
|
{
|
|
this->ItemLocation->SetValue(i,-1);
|
|
}
|
|
this->ItemLocation->Reset();
|
|
}
|
|
|
|
void vtkPriorityQueue::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Number Of Entries: " << this->MaxId + 1 << "\n";
|
|
os << indent << "Size: " << this->Size << "\n";
|
|
os << indent << "Extend size: " << this->Extend << "\n";
|
|
}
|
|
|
|
|