Tạo heap structure (đối với dấu đầu dòng thứ hai) và đặt từng nút trong bản đồ (đối với dấu đầu dòng).
EDIT: An thực hiện đống min Chúng tôi đã thực hiện một số thời gian trong
#ifndef MINHEAP_H
#define MINHEAP_H
//////////////////////// MinHeap with Map for Data ////////////////////////
template <class T, class M = int> class MinHeap {
T* array;
unsigned const int arr_max;
unsigned int elements;
M map;
void percolate_down(unsigned int i=0) {
unsigned int n = elements-1, min;
do {
unsigned int l = 2*i + 1, r = 2*i + 2;
if (l <= n && array[i] > array[l]) min = l;
else min = i;
if (r <= n && array[i] > array[r] && array[l] > array[r]) min = r;
if (i != min) {
T temp = array[i];
array[i] = array[min];
array[min] = temp;
map.update(array[i], i);
map.update(array[min], min);
i = min;
} else break;
} while (i < n);
}
void percolate_up(unsigned int i) {
while (i && array[(i-1)/2] > array[i]) {
T temp = array[i];
array[i] = array[(i-1)/2];
array[(i-1)/2] = temp;
map.update(array[i], i);
map.update(array[(i-1)/2], (i-1)/2);
i = (i-1)/2;
}
}
public:
MinHeap(const int max) : array(new T[max]), arr_max(max), elements(0), map(max) {}
~MinHeap(void) { delete[] array; }
bool empty(void) const { return elements == 0; }
unsigned int capacity(void) const { return arr_max; }
unsigned int size(void) const { return elements; }
const M& heapmap(void) const { return map; }
const T& peek(unsigned int i=0) const { return array[i]; }
bool insert(T& element) {
if (arr_max == elements) return false;
unsigned int k = elements++;
map.update(element, k);
array[k] = element;
percolate_up(k);
return true;
}
unsigned int mass_insert(T copy[], unsigned int n) {
unsigned int i = 0;
for(; i < n ; i++) if (!insert(copy[i])) break;
return i;
}
bool delete_min(void) {
if (elements == 0) return false;
map.update(array[0], arr_max+1);
array[0] = array[--elements];
map.update(array[0], 0);
percolate_down();
return true;
}
bool delete_element(unsigned int i) {
if (i > elements) return false;
map.update(array[i], arr_max+1);
T temp = array[i];
array[i] = array[--elements];
map.update(array[i], i);
if (array[i] > temp) percolate_down(i);
else if (temp > array[i]) percolate_up(i);
return true;
}
bool update(unsigned int i, T& element) {
if (i > elements) return false;
map.update(array[i], arr_max+1);
T temp = array[i];
array[i] = element;
map.update(array[i], i);
if (array[i] > temp) percolate_down(i);
else if (temp > array[i]) percolate_up(i);
return true;
}
// void print() { using namespace std; for (unsigned int i=0 ; i < elements ; i++) cout << array[i] << " | "; cout << endl; }
// Iterators
/*
friend class Const_Iterator;
class Const_Iterator {
MinHeap<T>* heap;
unsigned int index;
Const_Iterator(MinHeap<T>* h, unsigned int i) : heap(h), index(i) {}
public:
Const_Iterator(const Const_Iterator& clone) : heap(clone.heap), index(clone.index) {}
friend Const_Iterator MinHeap<T>::begin(void);
};
Const_Iterator begin(void) { return Const_Iterator(this, 0); }
*/
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////// MinHeap without Map for Data ////////////////////////
template <class T> class MinHeap <T, int> {
T* array;
unsigned const int arr_max;
unsigned int elements;
void percolate_down(unsigned int i=0) {
unsigned int n = elements-1, min;
do {
unsigned int l = 2*i + 1, r = 2*i + 2;
if (l <= n && array[i] > array[l]) min = l;
else min = i;
if (r <= n && array[i] > array[r] && array[l] > array[r]) min = r;
if (i != min) {
T temp = array[i];
array[i] = array[min];
array[min] = temp;
i = min;
} else break;
} while (i < n);
}
void percolate_up(unsigned int i) {
while (i && array[(i-1)/2] > array[i]) {
T temp = array[i];
array[i] = array[(i-1)/2];
array[(i-1)/2] = temp;
i = (i-1)/2;
}
}
public:
MinHeap(const int max) : array(new T[max]), arr_max(max), elements(0) {}
~MinHeap(void) { delete[] array; }
bool empty(void) const { return elements == 0; }
unsigned int capacity(void) const { return arr_max; }
unsigned int size(void) const { return elements; }
const T& peek(unsigned int i=0) const { return array[i]; }
bool insert(T& element) {
if (arr_max == elements) return false;
unsigned int k = elements++;
array[k] = element;
percolate_up(k);
return true;
}
unsigned int mass_insert(T copy[], unsigned int n) {
unsigned int i = 0;
for(; i < n ; i++) if (!insert(copy[i])) break;
return i;
}
bool delete_min(void) {
if (elements == 0) return false;
array[0] = array[--elements];
percolate_down();
return true;
}
bool delete_element(unsigned int i) {
if (i > elements) return false;
T temp = array[i];
array[i] = array[--elements];
if (array[i] > temp) percolate_down(i);
else if (temp > array[i]) percolate_up(i);
return true;
}
bool update(unsigned int i, T& element) {
if (i > elements) return false;
T temp = array[i];
array[i] = element;
if (array[i] > temp) percolate_down(i);
else if (temp > array[i]) percolate_up(i);
return true;
}
// void print() { using namespace std; for (unsigned int i=0 ; i < elements ; i++) cout << array[i] << " | "; cout << endl; }
};
//////////////////////////////////////////////////////////////////////////////
#endif // MINHEAP_H
Nguồn
2011-08-30 22:57:40
Đây là một giải pháp tốt! Bạn nên lưu ý những nhược điểm quá: giữ chúng được đồng bộ hóa và sử dụng bộ nhớ. –
@Mooing Duck- Lý tưởng nhất, bạn sẽ quấn nó lên trong lớp riêng của nó để bạn không thể khiến hai người không đồng bộ với nhau. Và có, có sử dụng bộ nhớ nhiều hơn, mặc dù nó chỉ là một yếu tố liên tục hơn là chỉ có một trong hai cấu trúc. – templatetypedef
@templatetypedef: +1, nhưng một dải Fibonacci chứ không phải là một heap nhị phân (hoặc nary-heap) - thực sự? Tôi hiểu rằng các giới hạn phân bổ lý thuyết có thể tốt hơn, nhưng đây có phải là trường hợp thực tế không? Xem, ví dụ: http://stackoverflow.com/questions/504823/has-anyone-actually-implemented-a-fibonacci-heap-efficiently. Ngoài ra, không Fibonaaci heaps thực sự có trường hợp xấu nhất tồi tệ nhất cho một số hoạt động? –