added HashList::inject() and HashTable::inject().
improved HashTable::upsert(). added HashList::ensert() and HashTable::ensert(). started porting rbt to RedBlackTree
This commit is contained in:
parent
06dbccbc06
commit
14f5a8a9b3
@ -44,7 +44,7 @@ struct HashListHasher
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct HashListComparator
|
||||
struct HashListEqualer
|
||||
{
|
||||
bool operator() (const T& v1, const T& v2) const
|
||||
{
|
||||
@ -76,18 +76,18 @@ struct HashListResizer
|
||||
/// For a hash value of hc, this->nodes[hc * 2] points to the first node and
|
||||
/// this->nodes[hc * 2 + 1] ponits to the last node.
|
||||
|
||||
template <typename T, typename HASHER = HashListHasher<T>, typename COMPARATOR = HashListComparator<T>, typename RESIZER = HashListResizer >
|
||||
template <typename T, typename HASHER = HashListHasher<T>, typename EQUALER = HashListEqualer<T>, typename RESIZER = HashListResizer >
|
||||
class HashList: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef LinkedList<T,COMPARATOR> DatumList;
|
||||
typedef LinkedList<T,EQUALER> DatumList;
|
||||
typedef typename DatumList::Node Node;
|
||||
typedef typename DatumList::Iterator Iterator;
|
||||
typedef typename DatumList::ConstIterator ConstIterator;
|
||||
typedef HashList<T,HASHER,COMPARATOR,RESIZER> SelfType;
|
||||
typedef HashList<T,HASHER,EQUALER,RESIZER> SelfType;
|
||||
|
||||
typedef HashListHasher<T> DefaultHasher;
|
||||
typedef HashListComparator<T> DefaultComparator;
|
||||
typedef HashListEqualer<T> DefaultEqualer;
|
||||
typedef HashListResizer DefaultResizer;
|
||||
|
||||
enum
|
||||
@ -304,7 +304,7 @@ protected:
|
||||
do
|
||||
{
|
||||
T& t = np->value;
|
||||
if (this->comparator(datum, t)) return np;
|
||||
if (this->equaler(datum, t)) return np;
|
||||
if (np == this->nodes[tail]) break;
|
||||
np = np->getNextNode ();
|
||||
}
|
||||
@ -314,10 +314,10 @@ protected:
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
template <typename MT, typename MCOMPARATOR>
|
||||
template <typename MT, typename MEQUALER>
|
||||
Node* heterofind_node (const MT& datum, qse_size_t hc) const
|
||||
{
|
||||
MCOMPARATOR is_equal;
|
||||
MEQUALER m_Equaler;
|
||||
|
||||
qse_size_t head, tail;
|
||||
Node* np;
|
||||
@ -330,7 +330,7 @@ protected:
|
||||
do
|
||||
{
|
||||
T& t = np->value;
|
||||
if (is_equal(datum, t)) return np;
|
||||
if (m_Equaler(datum, t)) return np;
|
||||
if (np == this->nodes[tail]) break;
|
||||
np = np->getNextNode ();
|
||||
}
|
||||
@ -340,53 +340,6 @@ protected:
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
Node* insert_value (const T& datum, bool overwrite = true)
|
||||
{
|
||||
qse_size_t hc, head, tail;
|
||||
Node* np;
|
||||
|
||||
hc = this->hasher(datum) % this->node_capacity;
|
||||
head = hc << 1; tail = head + 1;
|
||||
|
||||
np = this->nodes[head];
|
||||
if (np)
|
||||
{
|
||||
do
|
||||
{
|
||||
T& t = np->value;
|
||||
if (this->comparator(datum, t))
|
||||
{
|
||||
if (!overwrite) return QSE_NULL;
|
||||
t = datum;
|
||||
return np;
|
||||
}
|
||||
|
||||
if (np == this->nodes[tail]) break;
|
||||
np = np->getNextNode ();
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (datum_list->getSize() >= threshold)
|
||||
{
|
||||
this->rehash ();
|
||||
hc = this->hasher(datum) % this->node_capacity;
|
||||
head = hc << 1; tail = head + 1;
|
||||
}
|
||||
|
||||
if (nodes[head] == QSE_NULL)
|
||||
{
|
||||
this->nodes[head] = this->datum_list->insert ((Node*)QSE_NULL, datum);
|
||||
this->nodes[tail] = this->nodes[head];
|
||||
}
|
||||
else
|
||||
{
|
||||
this->nodes[head] = this->datum_list->insert (this->nodes[head], datum);
|
||||
}
|
||||
|
||||
return this->nodes[head];
|
||||
}
|
||||
|
||||
public:
|
||||
Node* findNode (const T& datum)
|
||||
{
|
||||
@ -412,34 +365,34 @@ public:
|
||||
return &b->value;
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
Node* heterofindNode (const MT& datum)
|
||||
{
|
||||
MHASHER hash;
|
||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
||||
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
const Node* heterofindNode (const MT& datum) const
|
||||
{
|
||||
MHASHER hash;
|
||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
||||
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
T* heterofindValue(const MT& datum)
|
||||
{
|
||||
MHASHER hash;
|
||||
Node* b = this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
||||
Node* b = this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||
if (!b) return QSE_NULL;
|
||||
return &b->value;
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
const T* heterofindValue(const MT& datum) const
|
||||
{
|
||||
MHASHER hash;
|
||||
Node* b = this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
||||
Node* b = this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||
if (!b) return QSE_NULL;
|
||||
return &b->value;
|
||||
}
|
||||
@ -460,23 +413,82 @@ public:
|
||||
return this->find_node (datum);
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
Node* heterosearch (const MT& datum)
|
||||
{
|
||||
MHASHER hash;
|
||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
||||
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
const Node* heterosearch (const MT& datum) const
|
||||
{
|
||||
MHASHER hash;
|
||||
return this->heterofind_node<MT,MCOMPARATOR> (datum, hash(datum) % this->node_capacity);
|
||||
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
|
||||
}
|
||||
|
||||
Node* inject (const T& datum, int mode, bool* injected = QSE_NULL)
|
||||
{
|
||||
qse_size_t hc, head, tail;
|
||||
Node* np;
|
||||
|
||||
hc = this->hasher(datum) % this->node_capacity;
|
||||
head = hc << 1; tail = head + 1;
|
||||
|
||||
np = this->nodes[head];
|
||||
if (np)
|
||||
{
|
||||
do
|
||||
{
|
||||
T& t = np->value;
|
||||
if (this->equaler(datum, t))
|
||||
{
|
||||
if (injected) *injected = false;
|
||||
if (mode <= -1) return QSE_NULL; // failure
|
||||
if (mode >= 1) t = datum; // overwrite
|
||||
return np;
|
||||
}
|
||||
|
||||
if (np == this->nodes[tail]) break;
|
||||
np = np->getNextNode ();
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (datum_list->getSize() >= threshold)
|
||||
{
|
||||
this->rehash ();
|
||||
hc = this->hasher(datum) % this->node_capacity;
|
||||
head = hc << 1; tail = head + 1;
|
||||
}
|
||||
|
||||
if (nodes[head] == QSE_NULL)
|
||||
{
|
||||
this->nodes[head] = this->datum_list->insert ((Node*)QSE_NULL, datum);
|
||||
this->nodes[tail] = this->nodes[head];
|
||||
}
|
||||
else
|
||||
{
|
||||
this->nodes[head] = this->datum_list->insert (this->nodes[head], datum);
|
||||
}
|
||||
|
||||
if (injected) *injected = true;
|
||||
return this->nodes[head];
|
||||
}
|
||||
|
||||
Node* insert (const T& datum)
|
||||
{
|
||||
return this->insert_value (datum, false);
|
||||
return this->inject (datum, -1, QSE_NULL);
|
||||
}
|
||||
|
||||
Node* ensert (const T& datum)
|
||||
{
|
||||
return this->inject (datum, 0, QSE_NULL);
|
||||
}
|
||||
|
||||
Node* upsert (const T& datum)
|
||||
{
|
||||
return this->inject (datum, 1, QSE_NULL);
|
||||
}
|
||||
|
||||
Node* update (const T& datum)
|
||||
@ -486,11 +498,6 @@ public:
|
||||
return node;
|
||||
}
|
||||
|
||||
Node* upsert (const T& datum)
|
||||
{
|
||||
return this->insert_value (datum, true);
|
||||
}
|
||||
|
||||
int remove (const T& datum)
|
||||
{
|
||||
qse_size_t hc, head, tail;
|
||||
@ -505,7 +512,7 @@ public:
|
||||
do
|
||||
{
|
||||
T& t = np->value;
|
||||
if (this->comparator(datum, t))
|
||||
if (this->equaler(datum, t))
|
||||
{
|
||||
if (this->nodes[head] == this->nodes[tail])
|
||||
{
|
||||
@ -534,13 +541,13 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename MT, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MT, typename MHASHER, typename MEQUALER>
|
||||
int heteroremove (const MT& datum)
|
||||
{
|
||||
MHASHER hash;
|
||||
qse_size_t hc = hash(datum) % this->node_capacity;
|
||||
|
||||
Node* np = this->heterofind_node<MT,MCOMPARATOR> (datum, hc);
|
||||
Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc);
|
||||
if (np)
|
||||
{
|
||||
qse_size_t head, tail;
|
||||
@ -614,7 +621,7 @@ protected:
|
||||
mutable qse_size_t threshold;
|
||||
qse_size_t load_factor;
|
||||
HASHER hasher;
|
||||
COMPARATOR comparator;
|
||||
EQUALER equaler;
|
||||
RESIZER resizer;
|
||||
|
||||
void rehash ()
|
||||
|
@ -44,7 +44,7 @@ struct HashTableHasher
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct HashTableComparator
|
||||
struct HashTableEqualer
|
||||
{
|
||||
// it must return true if two values are equal
|
||||
bool operator() (const T& v1, const T& v2) const
|
||||
@ -55,15 +55,15 @@ struct HashTableComparator
|
||||
|
||||
typedef HashListResizer HashTableResizer;
|
||||
|
||||
template <typename K, typename V, typename HASHER = HashTableHasher<K>, typename COMPARATOR = HashTableComparator<K>, typename RESIZER = HashTableResizer>
|
||||
template <typename K, typename V, typename HASHER = HashTableHasher<K>, typename EQUALER = HashTableEqualer<K>, typename RESIZER = HashTableResizer>
|
||||
class HashTable: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef Association<K,V> Pair;
|
||||
typedef HashTable<K,V,HASHER,COMPARATOR,RESIZER> SelfType;
|
||||
typedef HashTable<K,V,HASHER,EQUALER,RESIZER> SelfType;
|
||||
|
||||
typedef HashTableHasher<K> DefaultHasher;
|
||||
typedef HashTableComparator<K> DefaultComparator;
|
||||
typedef HashTableEqualer<K> DefaultEqualer;
|
||||
typedef HashTableResizer DefaultResizer;
|
||||
|
||||
struct PairHasher
|
||||
@ -75,35 +75,35 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct PairComparator
|
||||
struct PairEqualer
|
||||
{
|
||||
qse_size_t operator() (const Pair& p1, const Pair& p2) const
|
||||
{
|
||||
COMPARATOR comparator;
|
||||
return comparator (p1.key, p2.key);
|
||||
EQUALER equaler;
|
||||
return equaler (p1.key, p2.key);
|
||||
}
|
||||
};
|
||||
|
||||
struct PairHeteroComparator
|
||||
struct PairHeteroEqualer
|
||||
{
|
||||
qse_size_t operator() (const K& p1, const Pair& p2) const
|
||||
{
|
||||
COMPARATOR is_equal;
|
||||
return is_equal (p1, p2.key);
|
||||
EQUALER equaler;
|
||||
return equaler (p1, p2.key);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MK, typename MCOMPARATOR>
|
||||
struct MHeteroComparator
|
||||
template <typename MK, typename MEQUALER>
|
||||
struct MHeteroEqualer
|
||||
{
|
||||
qse_size_t operator() (const MK& p1, const Pair& p2) const
|
||||
{
|
||||
MCOMPARATOR is_equal;
|
||||
return is_equal (p1, p2.key);
|
||||
MEQUALER mequaler;
|
||||
return mequaler (p1, p2.key);
|
||||
}
|
||||
};
|
||||
|
||||
typedef HashList<Pair,PairHasher,PairComparator,RESIZER> PairList;
|
||||
typedef HashList<Pair,PairHasher,PairEqualer,RESIZER> PairList;
|
||||
typedef typename PairList::Node PairNode;
|
||||
typedef typename PairList::Iterator Iterator;
|
||||
typedef typename PairList::ConstIterator ConstIterator;
|
||||
@ -180,6 +180,13 @@ public:
|
||||
return this->pair_list.getTailNode ();
|
||||
}
|
||||
|
||||
Pair* inject (const K& key, const V& value, int mode, bool* injected = QSE_NULL)
|
||||
{
|
||||
PairNode* node = this->pair_list.inject (Pair(key, value), mode, injected);
|
||||
if (!node) return QSE_NULL;
|
||||
return &node->value;
|
||||
}
|
||||
|
||||
Pair* insert (const K& key, const V& value)
|
||||
{
|
||||
PairNode* node = this->pair_list.insert (Pair(key, value));
|
||||
@ -187,20 +194,38 @@ public:
|
||||
return &node->value;
|
||||
}
|
||||
|
||||
Pair* upsert (const K& key, const V& value)
|
||||
Pair* ensert (const K& key, const V& value)
|
||||
{
|
||||
PairNode* node = this->pair_list.upsert (Pair(key, value));
|
||||
PairNode* node = this->pair_list.ensert (Pair(key, value));
|
||||
if (!node) return QSE_NULL;
|
||||
return &node->value;
|
||||
}
|
||||
|
||||
Pair* upsert (const K& key, const V& value)
|
||||
{
|
||||
//PairNode* node = this->pair_list.upsert (Pair(key, value));
|
||||
//if (!node) return QSE_NULL;
|
||||
//return &node->value;
|
||||
|
||||
// Don't call pair_list.upsert() to make sure that the 'key' object
|
||||
// itself remains identical after potential update operation.
|
||||
// pair_list.upsert() changes the Pair object as a whole. so this
|
||||
// trick is required.
|
||||
bool injected;
|
||||
PairNode* node = this->pair_list.inject (Pair(key, value), 0, &injected);
|
||||
QSE_ASSERT (node != QSE_NULL);
|
||||
Pair& pair = node->value;
|
||||
if (injected) pair.value = value;
|
||||
return &pair;
|
||||
}
|
||||
|
||||
Pair* update (const K& key, const V& value)
|
||||
{
|
||||
//PairNode* node = this->pair_list.update (Pair(key, value));
|
||||
//if (!node) return QSE_NULL;
|
||||
//return &node->value;
|
||||
|
||||
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroComparator> (key);
|
||||
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroEqualer> (key);
|
||||
if (!node) return QSE_NULL;
|
||||
Pair& pair = node->value;
|
||||
pair.value = value;
|
||||
@ -210,7 +235,7 @@ public:
|
||||
Pair* search (const K& key)
|
||||
{
|
||||
//PairNode* node = this->pair_list.update (Pair(key));
|
||||
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroComparator> (key);
|
||||
PairNode* node = this->pair_list.template heterofindNode<K,HASHER,PairHeteroEqualer> (key);
|
||||
if (!node) return QSE_NULL;
|
||||
return &node->value;
|
||||
}
|
||||
@ -218,32 +243,32 @@ public:
|
||||
int remove (const K& key)
|
||||
{
|
||||
//return this->pair_list.remove (Pair(key));
|
||||
return this->pair_list.template heteroremove<K,HASHER,PairHeteroComparator> (key);
|
||||
return this->pair_list.template heteroremove<K,HASHER,PairHeteroEqualer> (key);
|
||||
}
|
||||
|
||||
template <typename MK, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MK, typename MHASHER, typename MEQUALER>
|
||||
Pair* heterosearch (const MK& key)
|
||||
{
|
||||
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
|
||||
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MComparator> (key);
|
||||
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
|
||||
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MEqualer> (key);
|
||||
if (!node) return QSE_NULL;
|
||||
return &node->value;
|
||||
}
|
||||
|
||||
template <typename MK, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MK, typename MHASHER, typename MEQUALER>
|
||||
const Pair* heterosearch (const MK& key) const
|
||||
{
|
||||
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
|
||||
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MComparator> (key);
|
||||
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
|
||||
PairNode* node = this->pair_list.template heterosearch<MK,MHASHER,MEqualer> (key);
|
||||
if (!node) return QSE_NULL;
|
||||
return &node->value;
|
||||
}
|
||||
|
||||
template <typename MK, typename MHASHER, typename MCOMPARATOR>
|
||||
template <typename MK, typename MHASHER, typename MEQUALER>
|
||||
int heteroremove (const MK& key)
|
||||
{
|
||||
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
|
||||
return this->pair_list.template heteroremove<MK,MHASHER,MComparator> (key);
|
||||
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
|
||||
return this->pair_list.template heteroremove<MK,MHASHER,MEqualer> (key);
|
||||
}
|
||||
|
||||
void clear (bool clear_mpool = false)
|
||||
|
@ -34,14 +34,14 @@
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
template <typename T, typename COMPARATOR> class LinkedList;
|
||||
template <typename T, typename EQUALER> class LinkedList;
|
||||
|
||||
template <typename T, typename COMPARATOR>
|
||||
template <typename T, typename EQUALER>
|
||||
class LinkedListNode
|
||||
{
|
||||
public:
|
||||
friend class LinkedList<T,COMPARATOR>;
|
||||
typedef LinkedListNode<T,COMPARATOR> SelfType;
|
||||
friend class LinkedList<T,EQUALER>;
|
||||
typedef LinkedListNode<T,EQUALER> SelfType;
|
||||
|
||||
T value; // you can use this variable or accessor functions below
|
||||
|
||||
@ -79,12 +79,12 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename COMPARATOR, typename NODE, typename GET_T>
|
||||
template <typename T, typename EQUALER, typename NODE, typename GET_T>
|
||||
class LinkedListIterator {
|
||||
public:
|
||||
friend class LinkedList<T,COMPARATOR>;
|
||||
friend class LinkedList<T,EQUALER>;
|
||||
typedef NODE Node;
|
||||
typedef LinkedListIterator<T,COMPARATOR,NODE,GET_T> SelfType;
|
||||
typedef LinkedListIterator<T,EQUALER,NODE,GET_T> SelfType;
|
||||
|
||||
LinkedListIterator (): current(QSE_NULL) {}
|
||||
LinkedListIterator (Node* node): current(node) {}
|
||||
@ -178,7 +178,7 @@ protected:
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct LinkedListComparator
|
||||
struct LinkedListEqualer
|
||||
{
|
||||
// it must return true if two values are equal
|
||||
bool operator() (const T& v1, const T& v2) const
|
||||
@ -188,17 +188,17 @@ struct LinkedListComparator
|
||||
};
|
||||
|
||||
///
|
||||
/// The LinkedList<T,COMPARATOR> class provides a template for a doubly-linked list.
|
||||
/// The LinkedList<T,EQUALER> class provides a template for a doubly-linked list.
|
||||
///
|
||||
template <typename T, typename COMPARATOR = LinkedListComparator<T> > class LinkedList: public Mmged
|
||||
template <typename T, typename EQUALER = LinkedListEqualer<T> > class LinkedList: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef LinkedList<T,COMPARATOR> SelfType;
|
||||
typedef LinkedListNode<T,COMPARATOR> Node;
|
||||
typedef LinkedListIterator<T,COMPARATOR,Node,T> Iterator;
|
||||
typedef LinkedListIterator<T,COMPARATOR,const Node,const T> ConstIterator;
|
||||
typedef LinkedList<T,EQUALER> SelfType;
|
||||
typedef LinkedListNode<T,EQUALER> Node;
|
||||
typedef LinkedListIterator<T,EQUALER,Node,T> Iterator;
|
||||
typedef LinkedListIterator<T,EQUALER,const Node,const T> ConstIterator;
|
||||
|
||||
typedef LinkedListComparator<T> DefaultComparator;
|
||||
typedef LinkedListEqualer<T> DefaultEqualer;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -270,7 +270,7 @@ public:
|
||||
|
||||
bool isEmpty () const
|
||||
{
|
||||
return this->node_count == 0;
|
||||
return this->node_count <= 0;
|
||||
}
|
||||
|
||||
/// The insertNode() function inserts an externally created \a node
|
||||
@ -576,7 +576,7 @@ public:
|
||||
{
|
||||
for (Node* p = this->head_node; p; p = p->next)
|
||||
{
|
||||
if (this->comparator (value, p->value)) return p;
|
||||
if (this->equaler (value, p->value)) return p;
|
||||
}
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -585,7 +585,7 @@ public:
|
||||
{
|
||||
for (Node* p = tail_node; p; p = p->prev)
|
||||
{
|
||||
if (this->comparator (value, p->value)) return p;
|
||||
if (this->equaler (value, p->value)) return p;
|
||||
}
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -594,7 +594,7 @@ public:
|
||||
{
|
||||
for (Node* p = head; p; p = p->next)
|
||||
{
|
||||
if (this->comparator (value, p->value)) return p;
|
||||
if (this->equaler (value, p->value)) return p;
|
||||
}
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -603,7 +603,7 @@ public:
|
||||
{
|
||||
for (Node* p = tail; p; p = p->prev)
|
||||
{
|
||||
if (this->comparator (value, p->value)) return p;
|
||||
if (this->equaler (value, p->value)) return p;
|
||||
}
|
||||
return QSE_NULL;
|
||||
}
|
||||
@ -613,7 +613,7 @@ public:
|
||||
qse_size_t index = 0;
|
||||
for (Node* p = this->head_node; p; p = p->next)
|
||||
{
|
||||
if (this->comparator (value, p->value)) return index;
|
||||
if (this->equaler (value, p->value)) return index;
|
||||
index++;
|
||||
}
|
||||
return INVALID_INDEX;
|
||||
@ -625,7 +625,7 @@ public:
|
||||
for (Node* p = tail_node; p; p = p->prev)
|
||||
{
|
||||
index--;
|
||||
if (this->comparator (value, p->value)) return index;
|
||||
if (this->equaler (value, p->value)) return index;
|
||||
}
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
@ -696,7 +696,7 @@ public:
|
||||
|
||||
protected:
|
||||
Mpool mp;
|
||||
COMPARATOR comparator;
|
||||
EQUALER equaler;
|
||||
Node* head_node;
|
||||
Node* tail_node;
|
||||
qse_size_t node_count;
|
||||
|
@ -52,6 +52,7 @@ pkginclude_HEADERS = \
|
||||
if ENABLE_CXX
|
||||
pkginclude_HEADERS += \
|
||||
Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp
|
||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
|
||||
RedBlackTree.hpp
|
||||
endif
|
||||
|
||||
|
@ -52,7 +52,8 @@ build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@ENABLE_CXX_TRUE@am__append_1 = \
|
||||
@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||
@ENABLE_CXX_TRUE@ Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp
|
||||
@ENABLE_CXX_TRUE@ Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp HashTable.hpp \
|
||||
@ENABLE_CXX_TRUE@ RedBlackTree.hpp
|
||||
|
||||
subdir = include/qse/cmn
|
||||
DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \
|
||||
@ -92,7 +93,7 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.h \
|
||||
sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \
|
||||
utf8.h xma.h Mmgr.hpp StdMmgr.hpp HeapMmgr.hpp Mmged.hpp \
|
||||
Mpool.hpp Association.hpp LinkedList.hpp HashList.hpp \
|
||||
HashTable.hpp
|
||||
HashTable.hpp RedBlackTree.hpp
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
|
166
qse/include/qse/cmn/RedBlackTree.hpp
Normal file
166
qse/include/qse/cmn/RedBlackTree.hpp
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _QSE_CMN_REDBLACKTREE_HPP_
|
||||
#define _QSE_CMN_REDBLACKTREE_HPP_
|
||||
|
||||
#include <qse/Types.hpp>
|
||||
#include <qse/cmn/Mpool.hpp>
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_BEGIN_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
class RedBlackTreeNode
|
||||
{
|
||||
public:
|
||||
friend class RedBlackTree<T>;
|
||||
typedef RedBlackTreeNode<T> SelfType;
|
||||
|
||||
enum
|
||||
{
|
||||
RED,
|
||||
BLACK
|
||||
};
|
||||
|
||||
T value; // you can use this variable or accessor functions below
|
||||
|
||||
protected:
|
||||
SelfType* parent;
|
||||
SelfType* child[2]; // left and right
|
||||
|
||||
public:
|
||||
T& getValue () { return this->value; }
|
||||
const T& getValue () const { return this->value; }
|
||||
void setValue (const T& v) { this->value = v; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct RedBlackTreeComparator
|
||||
{
|
||||
int operator() (const T& v1, const T& v2) const
|
||||
{
|
||||
return (v1 > v2)? 1:
|
||||
(v1 < v2)? -1: 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename COMPARATOR = RedBlackTreeComparator<T> >
|
||||
class RedBlackTree: public Mmged
|
||||
{
|
||||
public:
|
||||
typedef RedBlackTree<T,COMPARATOR> SelfType;
|
||||
|
||||
typedef RedBlackTreeHasher<T> DefaultHasher;
|
||||
typedef RedBlackTreeComparator<T> DefaultComparator;
|
||||
|
||||
RedBlackTree
|
||||
Mmgr* mmgr = QSE_NULL,
|
||||
qse_size_t mpb_size = 0): Mmged(mmgr)
|
||||
{
|
||||
}
|
||||
|
||||
RedBlackTree (const RedBlackTree& rbt)
|
||||
{
|
||||
}
|
||||
|
||||
~RedBlackTree ()
|
||||
{
|
||||
}
|
||||
|
||||
RedBlackTree& operator= (const RedBlackTree& rbt)
|
||||
{
|
||||
/* TODO */
|
||||
return *this;
|
||||
}
|
||||
|
||||
Mpool& getMpool ()
|
||||
{
|
||||
return this->mp;
|
||||
}
|
||||
|
||||
const Mpool& getMpool () const
|
||||
{
|
||||
return this->mp;
|
||||
}
|
||||
|
||||
qse_size_t getSize () const
|
||||
{
|
||||
return this->node_count;
|
||||
}
|
||||
|
||||
bool isEmpty () const
|
||||
{
|
||||
return this->node_count <= 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Node* inject (const T& datum, int mode, bool* injected = QSE_NULL)
|
||||
{
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
Node* insert (const T& datum)
|
||||
{
|
||||
return this->inject (datum, -1, QSE_NULL);
|
||||
}
|
||||
|
||||
Node* ensert (const T& datum)
|
||||
{
|
||||
return this->inject (datum, 0, QSE_NULL);
|
||||
}
|
||||
|
||||
Node* upsert (const T& datum)
|
||||
{
|
||||
return this->inject (datum, 1, QSE_NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
Node* update (const T& datum)
|
||||
{
|
||||
Node* node = this->find_node (datum);
|
||||
if (node) node->value = datum;
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Mpool mp;
|
||||
COMPARATOR comparator;
|
||||
|
||||
Node xnil; // internal node to present nil
|
||||
Node* root; // root node.
|
||||
qse_size_t node_count;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user