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.
		
		
		
		
		
			
		
			
				
					
					
						
							390 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							390 lines
						
					
					
						
							11 KiB
						
					
					
				| /**CFile*********************************************************************** | |
|  | |
|   FileName    [ntrHeap.c] | |
|  | |
|   PackageName [ntr] | |
|  | |
|   Synopsis    [Functions for heap-based priority queue.] | |
|  | |
|   Description [The functions in this file manage a priority queue implemented | |
|   as a heap. The first element of the heap is the one with the smallest key. | |
|   Refer to Chapter 7 of Cormen, Leiserson, and Rivest for the theory.] | |
|  | |
|   SeeAlso     [] | |
|  | |
|   Author      [Fabio Somenzi] | |
|  | |
|   Copyright   [Copyright (c) 1995-2012, Regents of the University of Colorado | |
|  | |
|   All rights reserved. | |
|  | |
|   Redistribution and use in source and binary forms, with or without | |
|   modification, are permitted provided that the following conditions | |
|   are met: | |
|  | |
|   Redistributions of source code must retain the above copyright | |
|   notice, this list of conditions and the following disclaimer. | |
|  | |
|   Redistributions in binary form must reproduce the above copyright | |
|   notice, this list of conditions and the following disclaimer in the | |
|   documentation and/or other materials provided with the distribution. | |
|  | |
|   Neither the name of the University of Colorado nor the names of its | |
|   contributors may be used to endorse or promote products derived from | |
|   this software without specific prior written permission. | |
|  | |
|   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
|   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
|   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
|   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
|   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
|   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
|   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
|   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
|   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
|   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
|   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
|   POSSIBILITY OF SUCH DAMAGE.] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| #include "ntr.h" | |
|  | |
| /*---------------------------------------------------------------------------*/ | |
| /* Constant declarations                                                     */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Stucture declarations                                                     */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Type declarations                                                         */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Variable declarations                                                     */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| #ifndef lint | |
| static char rcsid[] UTIL_UNUSED = "$Id: ntrHeap.c,v 1.6 2012/02/05 01:53:01 fabio Exp fabio $"; | |
| #endif | |
|  | |
| /*---------------------------------------------------------------------------*/ | |
| /* Macro declarations                                                        */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| #define PARENT(i)	(((i)-1)>>1) | |
| #define RIGHT(i)	(((i)+1)<<1) | |
| #define LEFT(i)		(((i)<<1)|1) | |
| #define ITEM(p,i)	((p)[i].item) | |
| #define KEY(p,i)	((p)[i].key) | |
|  | |
| /**AutomaticStart*************************************************************/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Static function prototypes                                                */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| static void ntrHeapify (NtrHeap *heap, int i); | |
| static int ntrHeapResize (NtrHeap *heap); | |
| 
 | |
| /**AutomaticEnd***************************************************************/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Definition of exported functions                                          */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Initializes a priority queue.] | |
|  | |
|   Description [Initializes a priority queue. Returns a pointer to the heap | |
|   if successful; NULL otherwise.] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [Ntr_FreeHeap] | |
|  | |
| ******************************************************************************/ | |
| NtrHeap * | |
| Ntr_InitHeap( | |
|   int size) | |
| { | |
|     NtrHeap *heap; | |
| 
 | |
|     heap = ALLOC(NtrHeap,1); | |
|     if (heap == NULL) return(NULL); | |
|     heap->size = size; | |
|     heap->nslots = 0; | |
|     heap->slots = ALLOC(NtrHeapSlot,size); | |
|     if (heap->slots == NULL) { | |
| 	FREE(heap); | |
| 	return(NULL); | |
|     } | |
|     return(heap); | |
| 
 | |
| } /* end of Ntr_InitHeap */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Frees a priority queue.] | |
|  | |
|   Description [] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [Ntr_InitHeap] | |
|  | |
| ******************************************************************************/ | |
| void | |
| Ntr_FreeHeap( | |
|   NtrHeap *heap) | |
| { | |
|     FREE(heap->slots); | |
|     FREE(heap); | |
|     return; | |
| 
 | |
| } /* end of Ntr_FreeHeap */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Inserts an item in a priority queue.] | |
|  | |
|   Description [Inserts an item in a priority queue. Returns 1 if successful; | |
|   0 otherwise.] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [Ntr_HeapExtractMin] | |
|  | |
| ******************************************************************************/ | |
| int | |
| Ntr_HeapInsert( | |
|   NtrHeap *heap, | |
|   void *item, | |
|   int key) | |
| { | |
|     NtrHeapSlot *slots; | |
|     int i = heap->nslots; | |
| 
 | |
|     if (i == heap->size && !ntrHeapResize(heap)) return(0); | |
|     slots = heap->slots; | |
|     heap->nslots++; | |
|     while (i > 0 && KEY(slots,PARENT(i)) > key) { | |
| 	ITEM(slots,i) = ITEM(slots,PARENT(i)); | |
| 	KEY(slots,i) = KEY(slots,PARENT(i)); | |
| 	i = PARENT(i); | |
|     } | |
|     ITEM(slots,i) = item; | |
|     KEY(slots,i) = key; | |
|     return(1); | |
| 
 | |
| } /* end of Ntr_HeapInsert */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Extracts the element with the minimum key from a priority | |
|   queue.] | |
|  | |
|   Description [Extracts the element with the minimum key from a priority | |
|   queue. Returns 1 if successful; 0 otherwise.] | |
|  | |
|   SideEffects [The minimum key and the associated item are returned as | |
|   side effects.] | |
|  | |
|   SeeAlso     [Ntr_HeapInsert] | |
|  | |
| ******************************************************************************/ | |
| int | |
| Ntr_HeapExtractMin( | |
|   NtrHeap *heap, | |
|   void *item, | |
|   int *key) | |
| { | |
|     NtrHeapSlot *slots = heap->slots; | |
| 
 | |
|     if (heap->nslots == 0) return(0); | |
|     *(void **)item = ITEM(slots,0); | |
|     *key = KEY(slots,0); | |
|     heap->nslots--; | |
|     ITEM(slots,0) = ITEM(slots,heap->nslots); | |
|     KEY(slots,0) = KEY(slots,heap->nslots); | |
|     ntrHeapify(heap,0); | |
| 
 | |
|     return(1); | |
| 
 | |
| } /* end of Ntr_HeapExtractMin */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Returns the number of items in a priority queue.] | |
|  | |
|   Description [] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [] | |
|  | |
| ******************************************************************************/ | |
| int | |
| Ntr_HeapCount( | |
|   NtrHeap *heap) | |
| { | |
|     return(heap->nslots); | |
| 
 | |
| } /* end of Ntr_HeapCount */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Clones a priority queue.] | |
|  | |
|   Description [] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [Ntr_InitHeap] | |
|  | |
| ******************************************************************************/ | |
| NtrHeap * | |
| Ntr_HeapClone( | |
|   NtrHeap *source) | |
| { | |
|     NtrHeap *dest; | |
|     int i; | |
|     int nslots = source->nslots; | |
|     NtrHeapSlot *sslots = source->slots; | |
|     NtrHeapSlot *dslots; | |
| 
 | |
|     dest = Ntr_InitHeap(source->size); | |
|     if (dest == NULL) return(NULL); | |
|     dest->nslots = nslots; | |
|     dslots = dest->slots; | |
|     for (i = 0; i < nslots; i++) { | |
| 	KEY(dslots,i) = KEY(sslots,i); | |
| 	ITEM(dslots,i) = ITEM(sslots,i); | |
|     } | |
|     return(dest); | |
| 
 | |
| } /* end of Ntr_HeapClone */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Tests the heap property of a priority queue.] | |
|  | |
|   Description [Tests the heap property of a priority queue. Returns 1 if | |
|   Successful; 0 otherwise.] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [] | |
|  | |
| ******************************************************************************/ | |
| int | |
| Ntr_TestHeap( | |
|   NtrHeap *heap, | |
|   int i) | |
| { | |
|     NtrHeapSlot *slots = heap->slots; | |
|     int nslots = heap->nslots; | |
| 
 | |
|     if (i > 0 && KEY(slots,i) < KEY(slots,PARENT(i))) | |
| 	return(0); | |
|     if (LEFT(i) < nslots) { | |
| 	if (!Ntr_TestHeap(heap,LEFT(i))) | |
| 	    return(0); | |
|     } | |
|     if (RIGHT(i) < nslots) { | |
| 	if (!Ntr_TestHeap(heap,RIGHT(i))) | |
| 	    return(0); | |
|     } | |
|     return(1); | |
| 
 | |
| } /* end of Ntr_TestHeap */ | |
| 
 | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Definition of static functions                                            */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Maintains the heap property of a priority queue.] | |
|  | |
|   Description [] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [Ntr_HeapExtractMin] | |
|  | |
| ******************************************************************************/ | |
| static void | |
| ntrHeapify( | |
|   NtrHeap *heap, | |
|   int i) | |
| { | |
|     int smallest; | |
|     int left = LEFT(i); | |
|     int right = RIGHT(i); | |
|     int nslots = heap->nslots; | |
|     NtrHeapSlot *slots = heap->slots; | |
|     int key = KEY(slots,i); | |
| 
 | |
|     if (left < nslots && KEY(slots,left) < key) { | |
| 	smallest = left; | |
|     } else { | |
| 	smallest = i; | |
|     } | |
|     if (right < nslots && KEY(slots,right) < KEY(slots,smallest)) { | |
| 	smallest = right; | |
|     } | |
|     if (smallest != i) { | |
| 	void *item = ITEM(slots,i); | |
| 	KEY(slots,i) = KEY(slots,smallest); | |
| 	ITEM(slots,i) = ITEM(slots,smallest); | |
| 	KEY(slots,smallest) = key; | |
| 	ITEM(slots,smallest) = item; | |
| 	ntrHeapify(heap,smallest); | |
|     } | |
| 
 | |
|     return; | |
| 
 | |
| } /* end of ntrHeapify */ | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Resizes a priority queue.] | |
|  | |
|   Description [Resizes a priority queue by doubling the number of | |
|   available slots.  Returns 1 if successful; 0 otherwise.] | |
|  | |
|   SideEffects [None] | |
|  | |
|   SeeAlso     [Ntr_HeapInsert] | |
|  | |
| ******************************************************************************/ | |
| static int | |
| ntrHeapResize( | |
|   NtrHeap *heap) | |
| { | |
|   int oldlength = heap->size; | |
|   int newlength = 2 * oldlength; | |
|   NtrHeapSlot *oldslots = heap->slots; | |
|   NtrHeapSlot *newslots = REALLOC(NtrHeapSlot, oldslots, newlength); | |
|   if (newslots == NULL) return 0; | |
|   heap->size = newlength; | |
|   heap->slots = newslots; | |
|   assert(Ntr_TestHeap(heap, 0)); | |
|   return 1; | |
| 
 | |
| } /* end of ntrHeapResize */
 |