#ifndef LG_HEAP_H
#define LG_HEAP_H
#undef LG_FREE_ALL
#define LG_FREE_ALL ;
static inline int LG_iheap_check
(
const LG_Element *restrict Heap, const int64_t *restrict Iheap, const int64_t n, const int64_t nheap )
{
char *msg = NULL ;
LG_ASSERT_MSG (Heap != NULL && Iheap != NULL && nheap >= 0 && n >= 0, -2000,
"Heap is invalid") ;
for (int64_t p = 1 ; p <= nheap ; p++)
{
LG_Element e = Heap [p] ;
int64_t name = e.name ;
LG_ASSERT_MSG (name >= 0 && name < n && p == Iheap [name], -2000,
"Heap is invalid") ;
}
for (int64_t name = 0 ; name < n ; name++)
{
int64_t p = Iheap [name] ;
if (p <= 0)
{
}
else
{
LG_ASSERT_MSG (p <= nheap, -2000, "position of object is invalid") ;
LG_Element e = Heap [p] ;
LG_ASSERT_MSG (e.name == name, -2000, "Heap is invalid") ;
}
}
return (GrB_SUCCESS) ;
}
static inline int LG_heap_check
(
const LG_Element *restrict Heap, const int64_t *restrict Iheap, const int64_t n, const int64_t nheap )
{
char *msg = NULL ;
LG_ASSERT_MSG (Heap != NULL && Iheap != NULL && nheap >= 0 && n >= 0, -2000,
"Heap is invalid") ;
#if 0#endif
for (int64_t p = 1 ; p <= nheap / 2 ; p++)
{
int64_t pleft = 2*p ; int64_t pright = pleft + 1 ;
LG_ASSERT_MSG (! (pleft <= nheap && Heap [p].key > Heap [pleft].key),
-2000, "the min-heap property is not satisfied") ;
LG_ASSERT_MSG (! (pright <= nheap && Heap [p].key > Heap [pright].key),
-2000, "the min-heap property is not satisfied") ;
}
return (LG_iheap_check (Heap, Iheap, n, nheap)) ;
}
static inline void LG_heapify
(
int64_t p, LG_Element *restrict Heap, int64_t *restrict Iheap, const int64_t n, const int64_t nheap )
{
ASSERT (Heap != NULL && Iheap != NULL) ;
if (p > nheap / 2 || nheap <= 1)
{
return ;
}
LG_Element e = Heap [p] ;
while (true)
{
int64_t pleft = 2*p ; int64_t pright = pleft + 1 ;
if (pright <= nheap)
{
LG_Element eleft = Heap [pleft] ;
LG_Element eright = Heap [pright] ;
if (eleft.key < eright.key)
{
if (e.key > eleft.key)
{
Heap [p] = eleft ;
Iheap [eleft.name] = p ;
p = pleft ;
}
else
{
Heap [p] = e ;
Iheap [e.name] = p ;
return ;
}
}
else
{
if (e.key > eright.key)
{
Heap [p] = eright ;
Iheap [eright.name] = p ;
p = pright ;
}
else
{
Heap [p] = e ;
Iheap [e.name] = p ;
return ;
}
}
}
else
{
if (pleft <= nheap)
{
LG_Element eleft = Heap [pleft] ;
if (e.key > eleft.key)
{
Heap [p] = eleft ;
Iheap [eleft.name] = p ;
p = pleft ;
}
}
Heap [p] = e ;
Iheap [e.name] = p ;
return ;
}
}
}
static inline void LG_heap_build
(
LG_Element *restrict Heap, int64_t *restrict Iheap, const int64_t n, const int64_t nheap )
{
ASSERT (Heap != NULL && nheap >= 0) ;
ASSERT (LG_iheap_check (Heap, Iheap, n, nheap)) ;
for (int64_t p = nheap / 2 ; p >= 1 ; p--)
{
LG_heapify (p, Heap, Iheap, n, nheap) ;
}
ASSERT (LG_heap_check (Heap, Iheap, n, nheap)) ;
}
static inline void LG_heap_delete
(
int64_t p, LG_Element *restrict Heap, int64_t *restrict Iheap, const int64_t n, int64_t *restrict nheap )
{
ASSERT (Heap != NULL && Iheap != NULL && (*nheap) >= 0) ;
ASSERT (p >= 1 && p <= (*nheap)) ;
LG_Element elast = Heap [*nheap] ; LG_Element edel = Heap [p] ; Heap [p] = elast ; Iheap [elast.name] = p ; Iheap [edel.name] = 0 ; (*nheap)-- ;
LG_heapify (p, Heap, Iheap, n, (*nheap)) ;
}
static inline void LG_heap_decrease_key
(
int64_t p, const LG_key_t new_key, LG_Element *restrict Heap, int64_t *restrict Iheap, const int64_t n, const int64_t nheap )
{
ASSERT (Heap != NULL && Iheap != NULL) ;
ASSERT (p >= 1 && p < nheap) ;
ASSERT (new_key < Heap [p].key) ;
Heap [p].key = new_key ;
int64_t parent = p/2 ;
while (p > 1 && Heap [parent].key > Heap [p].key)
{
LG_Element e = Heap [p] ;
Heap [p] = Heap [parent] ;
Heap [parent] = e ;
Iheap [Heap [p].name] = p ;
Iheap [Heap [parent].name] = parent ;
p = parent ;
parent = p/2 ;
}
}
#endif