#ifndef _LINEAR_HEAP_H_ #define _LINEAR_HEAP_H_ #include "Utility.h" class ListLinearHeap { private: ui n; // number vertices ui key_cap; // the maximum allowed key value ui min_key; // possible min key ui max_key; // possible max key ui *key_s; // key of vertices ui *head_s; // head of doubly-linked list for a specific weight ui *pre_s; // pre for doubly-linked list ui *next_s; // next for doubly-linked list public: ListLinearHeap(ui _n, ui _key_cap) { n = _n; key_cap = _key_cap; min_key = max_key = key_cap; head_s = key_s = pre_s = next_s = nullptr; } ~ListLinearHeap() { if(head_s != nullptr) { delete[] head_s; head_s = nullptr; } if(pre_s != nullptr) { delete[] pre_s; pre_s = nullptr; } if(next_s != nullptr) { delete[] next_s; next_s = nullptr; } if(key_s != nullptr) { delete[] key_s; key_s = nullptr; } } void init(ui _n, ui _key_cap, ui *_id_s, ui *_key_s) { if(key_s == nullptr) key_s = new ui[n]; if(pre_s == nullptr) pre_s = new ui[n]; if(next_s == nullptr) next_s = new ui[n]; if(head_s == nullptr) head_s = new ui[key_cap+1]; //assert(_key_cap <= key_cap); min_key = max_key = _key_cap; for(ui i = 0;i <= _key_cap;i ++) head_s[i] = n; for(ui i = 0;i < _n;i ++) { ui id = _id_s[i]; ui key = _key_s[id]; //assert(id < n); assert(key <= _key_cap); key_s[id] = key; pre_s[id] = n; next_s[id] = head_s[key]; if(head_s[key] != n) pre_s[head_s[key]] = id; head_s[key] = id; if(key < min_key) min_key = key; } } ui get_key(ui id) { return key_s[id]; } void get_ids(ui *vs, ui &vs_size) { for(ui i = min_key;i <= max_key;i ++) { for(ui id = head_s[i];id != n;id = next_s[id]) { vs[vs_size ++] = id; } } } bool get_min(ui &id, ui &key) {// return true if success, return false otherwise while(min_key <= max_key&&head_s[min_key] == n) ++ min_key; if(min_key > max_key) return false; id = head_s[min_key]; key = min_key; //assert(key_s[id] == key); return true; } bool pop_min(ui &id, ui &key) {// return true if success, return false otherwise while(min_key <= max_key&&head_s[min_key] == n) ++ min_key; if(min_key > max_key) return false; id = head_s[min_key]; key = min_key; key_s[id] = key_cap+1; //assert(key_s[id] == key); head_s[min_key] = next_s[id]; if(head_s[min_key] != n) pre_s[head_s[min_key]] = n; return true; } ui decrement(ui id, ui dec) { //assert(key_s[id] >= dec); if(key_s[id] > key_cap) return 0; if(pre_s[id] == n) { //assert(head_s[key_s[id]] == id); head_s[key_s[id]] = next_s[id]; if(next_s[id] != n) pre_s[next_s[id]] = n; } else { ui pid = pre_s[id]; next_s[pid] = next_s[id]; if(next_s[id] != n) pre_s[next_s[id]] = pid; } ui &key = key_s[id]; key -= dec; pre_s[id] = n; next_s[id] = head_s[key]; if(head_s[key] != n) pre_s[head_s[key]] = id; head_s[key] = id; if(key < min_key) min_key = key; return key; } }; #endif