-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbucket.h
121 lines (101 loc) · 2.46 KB
/
bucket.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifndef _BUCKET_H
#define _BUCKET_H
#include <functional>
#include <vector>
using namespace std;
#include "node.h"
class Bucket {
public:
Bucket(int num_bins);
void Clear();
void Add(Node *node, int index);
void Remove(Node *node, int index);
Node *RemoveMin();
Node *RemoveMax();
void Iterate(std::function<void(Node *node)> work) const;
int min() const { return min_; }
int max() const { return max_; }
int size() const { return size_; }
bool empty() const { return !size(); }
int lowerbound() const { return lowerbound_; }
void set_lowerbound(int lowerbound) { lowerbound_ = lowerbound; }
private:
void FindNewMin();
void FindNewMax();
vector<Node *> bins_;
int min_;
int max_;
int size_;
int lowerbound_ = 0;
};
Bucket::Bucket(int num_bins) : bins_(num_bins) { Clear(); }
void Bucket::Clear() {
for (auto &bin : bins_) bin = nullptr;
min_ = bins_.size() + 1;
max_ = -1;
size_ = 0;
}
void Bucket::Add(Node *node, int index) {
node->after_ = bins_[index];
bins_[index] = node;
if (!node->after_) {
// first node in a bins_
if (min_ > index) min_ = index;
if (max_ < index) max_ = index;
}
size_++;
}
// Note: this function is not tested
void Bucket::Remove(Node *node, int index) {
if (bins_[index] == node) {
bins_[index] = node->after_;
if (bins_[index] == nullptr) {
if (size_ > 1) {
if (index == min_) FindNewMin();
if (index == max_) FindNewMax();
} else {
min_ = bins_.size() + 1;
max_ = -1;
}
}
} else {
for (auto cursor = bins_[index]; cursor; cursor = cursor->after_) {
if (cursor->after_ == node) {
cursor->after_ = node->after_;
break;
}
}
}
size_--;
}
Node *Bucket::RemoveMin() {
auto *node = bins_[min_];
bins_[min_] = node->after_;
if (!node->after_) FindNewMin();
size_--;
return node;
}
Node *Bucket::RemoveMax() {
auto *node = bins_[max_];
bins_[max_] = node->after_;
if (!node->after_) FindNewMax();
size_--;
return node;
}
void Bucket::Iterate(std::function<void(Node *node)> work) const {
if (empty()) return;
for (int index = min_; index <= max_; ++index) {
for (auto cursor = bins_[index]; cursor;) {
auto next = cursor->after_;
work(cursor);
cursor = next;
}
}
}
void Bucket::FindNewMin() {
while (min_ < max_ && bins_[min_] == nullptr) min_++;
}
void Bucket::FindNewMax() {
while (min_ < max_ && bins_[max_] == nullptr) max_--;
}
#endif