-
Notifications
You must be signed in to change notification settings - Fork 0
/
treemm.h
114 lines (93 loc) · 2.86 KB
/
treemm.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
#ifndef TREEMULTIMAP_INCLUDED
#define TREEMULTIMAP_INCLUDED
#include <list>
#include <iostream>
template <typename KeyType, typename ValueType>
class TreeMultimap
{
public:
class Iterator
{
public:
Iterator() : m_isValid(false) {}
Iterator(typename std::list<ValueType>::iterator it,
typename std::list<ValueType>::iterator end)
: m_isValid(true), m_iterator(it), m_end(end) {
}
ValueType& get_value() const { return *m_iterator; }
bool is_valid() const { return m_isValid; }
void advance()
{
m_iterator++;
if (m_iterator == m_end) m_isValid = false;
}
private:
typename std::list<ValueType>::iterator m_iterator;
typename std::list<ValueType>::iterator m_end;
bool m_isValid;
};
TreeMultimap() : m_root(nullptr) {}
~TreeMultimap() { deleteNodes(m_root); }
void insert(const KeyType& key, const ValueType& value)
{
// if we don't have a head, create one
if (!m_root) {
m_root = new Node(key, value);
return;
}
// find the correct place to insert
Node* curr = m_root;
while(true) {
if (key < curr->key) {
if (curr->less == nullptr) {
curr->less = new Node(key, value);
return;
}
curr = curr->less;
}
else if (key == curr->key) {
curr->append(value);
return;
}
else {
if (curr->greater == nullptr) {
curr->greater = new Node(key, value);
return;
}
curr = curr->greater;
}
}
}
Iterator find(const KeyType& key) const
{
Node* curr = m_root;
// go down tree until correct location is found
while (curr != nullptr) {
if (key == curr->key)
return Iterator(curr->values.begin(), curr->values.end());
else if (key < curr->key)
curr = curr->less;
else
curr = curr->greater;
}
// value not found; return invalid iterator
return Iterator();
}
private:
struct Node {
Node(KeyType k, ValueType v) : less(nullptr), greater(nullptr), key(k), values({v}) {}
void append(ValueType value) { values.push_back(value); }
KeyType key;
std::list<ValueType> values;
Node* less;
Node* greater;
};
Node* m_root;
void deleteNodes(Node* current) {
if (!current) return;
deleteNodes(current->less);
deleteNodes(current->greater);
delete current;
}
};
#endif // TREEMULTIMAP_INCLUDED