home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- +
- + LEDA 2.1.1 11-15-1991
- +
- +
- + _k_heap.c
- +
- +
- + Copyright (c) 1991 by Max-Planck-Institut fuer Informatik
- + Im Stadtwald, 6600 Saarbruecken, FRG
- + All rights reserved.
- +
- *******************************************************************************/
-
-
- #include <LEDA/k_heap.h>
-
- #define SON1(i) (K*i+1)
- #define PARENT(i) ((i-1)/K)
-
-
- K_HEAP::K_HEAP(int n, int k)
- {
- K = k;
- Key = new ent[n];
- Inf = new ent[n];
- Item = new int[n];
- Pos = new int[n+1];
- for (int i=1;i<=n;i++) free_items.append(Ent(i));
- max_count = n; count = 0;
- }
-
- K_HEAP::~K_HEAP()
- {
- delete Key;
- delete Inf;
- delete Item;
- delete Pos;
- free_items.clear();
- }
-
- void K_HEAP::clear()
- { count = 0;
- free_items.clear();
- for (int i=1;i<=max_count;i++) free_items.append(Ent(i));
- }
-
- void K_HEAP::rise(int& pos, ent k, ent i)
- {
- register int parent = PARENT(pos);
-
- while (pos > 0 && cmp(Inf[parent],i) > 0 )
- { Inf[pos] = Inf[parent];
- Key[pos] = Key[parent];
- Item[pos] = Item[parent];
- Pos[Item[pos]] = pos;
- pos = parent;
- parent = PARENT(pos);
- }
-
- Inf[pos] = i;
- Key[pos] = k;
-
- }
-
- void K_HEAP::sink(int& current, ent k, ent i)
- {
- register int child = SON1(current);
-
- while (child < count)
- {
- int r = Min(count,child+K);
- for (int j=child+1;j<r;j++)
- if (cmp(Inf[j],Inf[child])<0 ) child = j;
-
- if (cmp(i,Inf[child])>0)
- { Inf[current] = Inf[child];
- Key[current] = Key[child];
- Item[current] = Item[child];
- Pos[Item[current]] = current;
- current = child;
- child = SON1(current);
- }
- else break;
- }
-
- Inf[current] = i;
- Key[current] = k;
- }
-
-
- void K_HEAP::decrease_inf(int it, ent i)
- {
- int pos = Pos[it];
- if (cmp(Inf[pos],i)<0)
- { cout << string ("INF = %d i = %d\n",Inf[pos],i);
- cout.flush();
- error_handler(1,"k-heap: inf too large in decrease_inf");
- }
-
- rise(pos,Key[pos],i);
- Pos[it] = pos;
- Item[pos] = it;
- }
-
-
- int K_HEAP::insert(ent k, ent i)
- {
- if (free_items.empty()) error_handler(1,"k_heap: overflow");
-
- int new_it = (int)free_items.head();
- free_items.pop();
-
- int p = count++;
-
- rise(p,k,i);
-
- Pos[new_it] = p;
- Item[p] = new_it;
-
- return new_it;
- }
-
- int K_HEAP::insert0(ent k, ent i)
- {
- if (free_items.empty()) error_handler(1,"k_heap: overflow");
-
- int new_it = (int)free_items.head();
- free_items.pop();
-
- Key[count] = k;
- Inf[count] = i;
- Item[count] = new_it;
- Pos[new_it] = count;
- count++;
-
- return new_it;
- }
-
-
-
- ent K_HEAP::del_item(int it)
- {
- int p = Pos[it];
-
- ent result = Key[p];
-
- count--;
-
- free_items.append(Ent(it));
-
- sink(p,Key[count],Inf[count]);
-
- Item[p] = Item[count];
- Pos[Item[p]]= p;
-
- return result;
- }
-
- void K_HEAP::print()
- {
- int i;
-
- for(i=0;i<count;i++)
- { print_key(Key[i]);
- cout << "-";
- print_inf(Inf[i]);
- cout << " ";
- }
- newline;
-
-
- cout << "ITEM: ";
- for(i=0;i<count;i++) cout << string(" %3d",Item[i]);
- newline;
-
- cout << "POS: ";
- for(i=0;i<count;i++) cout << string(" %3d",Pos[Item[i]]);
- newline;
-
- newline;
-
- }
-