a580e1 | 2000-09-27 | Fredrik Hübinette (Hubbe) | | #pike __REAL_VERSION__
|
a20af6 | 2000-09-26 | Fredrik Hübinette (Hubbe) | |
|
38cbfe | 2006-04-24 | Robert Hinn | |
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | |
class Element (mixed value)
{
|
1b47a4 | 2015-11-17 | Henrik Grubbström (Grubba) | | int pos = -1;
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | |
constant is_adt_heap_element = 1;
protected int `<(mixed other) { return value < other; }
protected int `>(mixed other) { return value > other; }
}
#define SWAP(X,Y) do{ mixed tmp=values[X]; (values[X]=values[Y])->pos = X; (values[Y]=tmp)->pos = Y; }while(0)
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | |
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | protected array(Element) values=allocate(10);
|
7ee5de | 2009-10-08 | Henrik Grubbström (Grubba) | | protected int num_values;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | |
|
09c8a0 | 2009-09-17 | Henrik Grubbström (Grubba) | | #ifdef ADT_HEAP_DEBUG
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | void verify_heap()
{
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | for(int e=0; e<num_values; e++) {
if (!values[e] || !values[e]->is_adt_heap_element)
error("Error in HEAP: Position %d has no element.\n", e);
if (values[e]->pos != e)
error("Error in HEAP: Element %d has invalid position: %d.\n",
e, values[e]->pos);
|
96ba74 | 2015-10-14 | Henrik Grubbström (Grubba) | | if(e && (values[(e-1)/2] > values[e]))
|
ab3b6d | 2003-05-03 | Martin Nilsson | | error("Error in HEAP (%d, %d) num_values=%d\n",
(e-1)/2, e, num_values);
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | }
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | }
#else
#define verify_heap()
#endif
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected void adjust_down(int elem)
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
while(1)
{
int child=elem*2+1;
if(child >= num_values) break;
|
82e790 | 2004-06-21 | Martin Nilsson | |
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | if(child+1==num_values || values[child] < values[child+1])
{
if(values[child] < values[elem])
{
SWAP(child, elem);
elem=child;
continue;
}
} else {
if(child+1 >= num_values) break;
|
82e790 | 2004-06-21 | Martin Nilsson | |
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | if(values[child+1] < values[elem])
{
SWAP(elem, child+1);
elem=child+1;
continue;
}
}
break;
}
}
|
9eaf1d | 2008-06-28 | Martin Nilsson | | protected int adjust_up(int elem)
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
int parent=(elem-1)/2;
|
4720a6 | 1999-12-30 | Fredrik Hübinette (Hubbe) | |
|
af0035 | 1999-12-31 | Fredrik Hübinette (Hubbe) | | if(elem && values[elem] < values[parent])
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
SWAP(elem, parent);
elem=parent;
|
af0035 | 1999-12-31 | Fredrik Hübinette (Hubbe) | | while(elem && (values[elem] < values[parent=(elem -1)/2]))
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
SWAP(elem, parent);
elem=parent;
}
adjust_down(elem);
return 1;
}
return 0;
}
|
38cbfe | 2006-04-24 | Robert Hinn | |
|
fe792a | 2015-08-13 | Henrik Grubbström (Grubba) | |
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | |
|
fe792a | 2015-08-13 | Henrik Grubbström (Grubba) | |
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | Element push(mixed value)
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | Element ret;
if (objectp(value) && value->is_adt_heap_element) {
ret = value;
} else {
ret = Element(value);
}
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | if(num_values >= sizeof(values))
|
4720a6 | 1999-12-30 | Fredrik Hübinette (Hubbe) | | values+=allocate(10+sizeof(values)/4);
|
82e790 | 2004-06-21 | Martin Nilsson | |
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | (values[num_values] = ret)->pos = num_values++;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | adjust_up(num_values-1);
verify_heap();
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | return ret;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | }
|
38cbfe | 2006-04-24 | Robert Hinn | |
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | |
Element adjust(mixed value)
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | int pos;
if (objectp(value) && value->is_adt_heap_element) {
pos = value->pos;
} else {
|
b30798 | 2015-09-17 | Henrik Grubbström (Grubba) | | pos = search(map(values, lambda(Element x) { return x?->value; }), value);
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | }
Element ret;
if(pos>=0) {
ret = values[pos];
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | if(!adjust_up(pos))
adjust_down(pos);
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | }
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | verify_heap();
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | return ret;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | }
|
ab3b6d | 2003-05-03 | Martin Nilsson | |
|
fe792a | 2015-08-13 | Henrik Grubbström (Grubba) | |
|
ab3b6d | 2003-05-03 | Martin Nilsson | | mixed pop()
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
if(!num_values)
error("Heap underflow!\n");
|
82e790 | 2004-06-21 | Martin Nilsson | |
|
1b47a4 | 2015-11-17 | Henrik Grubbström (Grubba) | | Element value = values[0];
value->pos = -1;
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | num_values--;
if(num_values)
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | {
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | (values[0] = values[num_values])->pos = 0;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | adjust_down(0);
|
82e790 | 2004-06-21 | Martin Nilsson | |
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | if(num_values * 3 + 10 < sizeof(values))
values=values[..num_values+10];
}
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | values[num_values]=0;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | verify_heap();
|
1b47a4 | 2015-11-17 | Henrik Grubbström (Grubba) | | return value->value;
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | | }
|
ab3b6d | 2003-05-03 | Martin Nilsson | |
int _sizeof() { return num_values; }
|
b78e3a | 1999-12-30 | Fredrik Hübinette (Hubbe) | |
|
38cbfe | 2006-04-24 | Robert Hinn | |
|
fe792a | 2015-08-13 | Henrik Grubbström (Grubba) | |
|
38cbfe | 2006-04-24 | Robert Hinn | | mixed peek()
{
if (!num_values)
return UNDEFINED;
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | return values[0]->value;
|
38cbfe | 2006-04-24 | Robert Hinn | | }
|
e88211 | 2015-08-13 | Henrik Grubbström (Grubba) | |
void remove(mixed value)
{
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | int pos;
if (objectp(value) && value->is_adt_heap_element) {
pos = value->pos;
} else {
|
b30798 | 2015-09-17 | Henrik Grubbström (Grubba) | | pos = search(map(values, lambda(Element x) { return x?->value; }), value);
|
dd3ae6 | 2015-09-10 | Henrik Grubbström (Grubba) | | }
|
e88211 | 2015-08-13 | Henrik Grubbström (Grubba) | | if ((pos < 0) || (pos >= num_values)) return;
|
1b47a4 | 2015-11-17 | Henrik Grubbström (Grubba) | | value = values[pos];
|
e88211 | 2015-08-13 | Henrik Grubbström (Grubba) | | values[pos] = values[--num_values];
values[num_values] = 0;
|
1b47a4 | 2015-11-17 | Henrik Grubbström (Grubba) | | value->pos = -1;
|
e88211 | 2015-08-13 | Henrik Grubbström (Grubba) | | if (pos < num_values) {
if (!adjust_up(pos))
adjust_down(pos);
}
|
1909c5 | 2015-08-13 | Henrik Grubbström (Grubba) | |
if(num_values * 3 + 10 < sizeof(values))
values=values[..num_values+10];
|
e88211 | 2015-08-13 | Henrik Grubbström (Grubba) | | verify_heap();
}
|