* AVLTree:
- Renamed to AVLTreeBase and moved it into its own header/source file.
- Renamed FindClose() to FindClosest().
- Added CheckTree() method for debugging purposes. It checks the validity
of the tree.
* Added a templatized class AVLTree which doesn't offer a map-like interface
like AVLTreeMap, but rather one similar to BOpenHashMap and SplayTree. It
is more convenient to use, if one wants to store objects that already
contain the key.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34526 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,366 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009, Ingo Weinhold <[email protected]>.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _KERNEL_UTIL_AVL_TREE_H
|
||||||
|
#define _KERNEL_UTIL_AVL_TREE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <util/AVLTreeBase.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
To be implemented by the definition:
|
||||||
|
|
||||||
|
typedef int Key;
|
||||||
|
typedef Foo Value;
|
||||||
|
|
||||||
|
AVLTreeNode* GetAVLTreeNode(Value* value) const;
|
||||||
|
Value* GetValue(AVLTreeNode* node) const;
|
||||||
|
int Compare(const Key& a, const Value* b) const;
|
||||||
|
int Compare(const Value* a, const Value* b) const;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
class AVLTree : protected AVLTreeCompare {
|
||||||
|
private:
|
||||||
|
typedef typename Definition::Key Key;
|
||||||
|
typedef typename Definition::Value Value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class Iterator;
|
||||||
|
class ConstIterator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AVLTree();
|
||||||
|
AVLTree(const Definition& definition);
|
||||||
|
virtual ~AVLTree();
|
||||||
|
|
||||||
|
inline int Count() const { return fTree.Count(); }
|
||||||
|
inline bool IsEmpty() const { return fTree.IsEmpty(); }
|
||||||
|
inline void Clear();
|
||||||
|
|
||||||
|
Value* RootNode() const;
|
||||||
|
|
||||||
|
inline Iterator GetIterator();
|
||||||
|
inline ConstIterator GetIterator() const;
|
||||||
|
|
||||||
|
inline Iterator GetIterator(Value* value);
|
||||||
|
inline ConstIterator GetIterator(Value* value) const;
|
||||||
|
|
||||||
|
Value* Find(const Key& key) const;
|
||||||
|
Value* FindClosest(const Key& key, bool less) const;
|
||||||
|
|
||||||
|
status_t Insert(Value* value, Iterator* iterator = NULL);
|
||||||
|
Value* Remove(const Key& key);
|
||||||
|
bool Remove(Value* key);
|
||||||
|
|
||||||
|
void CheckTree() const { fTree.CheckTree(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// AVLTreeCompare
|
||||||
|
virtual int CompareKeyNode(const void* key,
|
||||||
|
const AVLTreeNode* node);
|
||||||
|
virtual int CompareNodes(const AVLTreeNode* node1,
|
||||||
|
const AVLTreeNode* node2);
|
||||||
|
|
||||||
|
// definition shortcuts
|
||||||
|
inline AVLTreeNode* _GetAVLTreeNode(Value* value) const;
|
||||||
|
inline Value* _GetValue(const AVLTreeNode* node) const;
|
||||||
|
inline int _Compare(const Key& a, const Value* b);
|
||||||
|
inline int _Compare(const Value* a, const Value* b);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class Iterator;
|
||||||
|
friend class ConstIterator;
|
||||||
|
|
||||||
|
AVLTreeBase fTree;
|
||||||
|
Definition fDefinition;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// (need to implement it here, otherwise gcc 2.95.3 chokes)
|
||||||
|
class Iterator : public ConstIterator {
|
||||||
|
public:
|
||||||
|
inline Iterator()
|
||||||
|
:
|
||||||
|
ConstIterator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Iterator(const Iterator& other)
|
||||||
|
:
|
||||||
|
ConstIterator(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Remove()
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* node = ConstIterator::fTreeIterator.Remove()) {
|
||||||
|
AVLTree<Definition>* parent
|
||||||
|
= const_cast<AVLTree<Definition>*>(
|
||||||
|
ConstIterator::fParent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline Iterator(AVLTree<Definition>* parent,
|
||||||
|
const AVLTreeIterator& treeIterator)
|
||||||
|
: ConstIterator(parent, treeIterator)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class AVLTree<Definition>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
class AVLTree<Definition>::ConstIterator {
|
||||||
|
public:
|
||||||
|
inline ConstIterator()
|
||||||
|
:
|
||||||
|
fParent(NULL),
|
||||||
|
fTreeIterator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ConstIterator(const ConstIterator& other)
|
||||||
|
:
|
||||||
|
fParent(other.fParent),
|
||||||
|
fTreeIterator(other.fTreeIterator)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool HasCurrent() const
|
||||||
|
{
|
||||||
|
return fTreeIterator.Current();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Value* Current()
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* node = fTreeIterator.Current())
|
||||||
|
return fParent->_GetValue(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool HasNext() const
|
||||||
|
{
|
||||||
|
return fTreeIterator.HasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Value* Next()
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* node = fTreeIterator.Next())
|
||||||
|
return fParent->_GetValue(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Value* Previous()
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* node = fTreeIterator.Previous())
|
||||||
|
return fParent->_GetValue(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ConstIterator& operator=(const ConstIterator& other)
|
||||||
|
{
|
||||||
|
fParent = other.fParent;
|
||||||
|
fTreeIterator = other.fTreeIterator;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline ConstIterator(const AVLTree<Definition>* parent,
|
||||||
|
const AVLTreeIterator& treeIterator)
|
||||||
|
{
|
||||||
|
fParent = parent;
|
||||||
|
fTreeIterator = treeIterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class AVLTree<Definition>;
|
||||||
|
|
||||||
|
const AVLTree<Definition>* fParent;
|
||||||
|
AVLTreeIterator fTreeIterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
AVLTree<Definition>::AVLTree()
|
||||||
|
:
|
||||||
|
fTree(this),
|
||||||
|
fDefinition()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
AVLTree<Definition>::AVLTree(const Definition& definition)
|
||||||
|
:
|
||||||
|
fTree(this),
|
||||||
|
fDefinition(definition)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
AVLTree<Definition>::~AVLTree()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline void
|
||||||
|
AVLTree<Definition>::Clear()
|
||||||
|
{
|
||||||
|
fTree.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline typename AVLTree<Definition>::Value*
|
||||||
|
AVLTree<Definition>::RootNode() const
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* root = fTree.Root())
|
||||||
|
return _GetValue(root);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline typename AVLTree<Definition>::Iterator
|
||||||
|
AVLTree<Definition>::GetIterator()
|
||||||
|
{
|
||||||
|
return Iterator(this, fTree.GetIterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline typename AVLTree<Definition>::ConstIterator
|
||||||
|
AVLTree<Definition>::GetIterator() const
|
||||||
|
{
|
||||||
|
return ConstIterator(this, fTree.GetIterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline typename AVLTree<Definition>::Iterator
|
||||||
|
AVLTree<Definition>::GetIterator(Value* value)
|
||||||
|
{
|
||||||
|
return Iterator(this, fTree.GetIterator(_GetAVLTreeNode(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline typename AVLTree<Definition>::ConstIterator
|
||||||
|
AVLTree<Definition>::GetIterator(Value* value) const
|
||||||
|
{
|
||||||
|
return ConstIterator(this, fTree.GetIterator(_GetAVLTreeNode(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
typename AVLTree<Definition>::Value*
|
||||||
|
AVLTree<Definition>::Find(const Key& key) const
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* node = fTree.Find(&key))
|
||||||
|
return _GetValue(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
typename AVLTree<Definition>::Value*
|
||||||
|
AVLTree<Definition>::FindClosest(const Key& key, bool less) const
|
||||||
|
{
|
||||||
|
if (AVLTreeNode* node = fTree.FindClosest(&key, less))
|
||||||
|
return _GetValue(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
status_t
|
||||||
|
AVLTree<Definition>::Insert(Value* value, Iterator* iterator)
|
||||||
|
{
|
||||||
|
AVLTreeNode* node = _GetAVLTreeNode(value);
|
||||||
|
status_t error = fTree.Insert(node);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (iterator != NULL)
|
||||||
|
*iterator = Iterator(this, fTree.GetIterator(node));
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
typename AVLTree<Definition>::Value*
|
||||||
|
AVLTree<Definition>::Remove(const Key& key)
|
||||||
|
{
|
||||||
|
AVLTreeNode* node = fTree.Remove(&key);
|
||||||
|
return node != NULL ? _GetValue(node) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
bool
|
||||||
|
AVLTree<Definition>::Remove(Value* value)
|
||||||
|
{
|
||||||
|
return fTree.Remove(_GetAVLTreeNode(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
int
|
||||||
|
AVLTree<Definition>::CompareKeyNode(const void* key,
|
||||||
|
const AVLTreeNode* node)
|
||||||
|
{
|
||||||
|
return _Compare(*(const Key*)key, _GetValue(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
int
|
||||||
|
AVLTree<Definition>::CompareNodes(const AVLTreeNode* node1,
|
||||||
|
const AVLTreeNode* node2)
|
||||||
|
{
|
||||||
|
return _Compare(_GetValue(node1), _GetValue(node2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline AVLTreeNode*
|
||||||
|
AVLTree<Definition>::_GetAVLTreeNode(Value* value) const
|
||||||
|
{
|
||||||
|
return fDefinition.GetAVLTreeNode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline typename AVLTree<Definition>::Value*
|
||||||
|
AVLTree<Definition>::_GetValue(const AVLTreeNode* node) const
|
||||||
|
{
|
||||||
|
return fDefinition.GetValue(const_cast<AVLTreeNode*>(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline int
|
||||||
|
AVLTree<Definition>::_Compare(const Key& a, const Value* b)
|
||||||
|
{
|
||||||
|
return fDefinition.Compare(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Definition>
|
||||||
|
inline int
|
||||||
|
AVLTree<Definition>::_Compare(const Value* a, const Value* b)
|
||||||
|
{
|
||||||
|
return fDefinition.Compare(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _KERNEL_UTIL_AVL_TREE_H
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2003-2009, Ingo Weinhold <[email protected]>.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _KERNEL_UTIL_AVL_TREE_BASE_H
|
||||||
|
#define _KERNEL_UTIL_AVL_TREE_BASE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
class AVLTreeIterator;
|
||||||
|
|
||||||
|
|
||||||
|
struct AVLTreeNode {
|
||||||
|
AVLTreeNode* parent;
|
||||||
|
AVLTreeNode* left;
|
||||||
|
AVLTreeNode* right;
|
||||||
|
int balance_factor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AVLTreeCompare {
|
||||||
|
public:
|
||||||
|
virtual ~AVLTreeCompare();
|
||||||
|
|
||||||
|
virtual int CompareKeyNode(const void* key,
|
||||||
|
const AVLTreeNode* node) = 0;
|
||||||
|
virtual int CompareNodes(const AVLTreeNode* node1,
|
||||||
|
const AVLTreeNode* node2) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AVLTreeBase {
|
||||||
|
public:
|
||||||
|
AVLTreeBase(AVLTreeCompare* compare);
|
||||||
|
~AVLTreeBase();
|
||||||
|
|
||||||
|
inline int Count() const { return fNodeCount; }
|
||||||
|
inline bool IsEmpty() const { return (fNodeCount == 0); }
|
||||||
|
void MakeEmpty();
|
||||||
|
|
||||||
|
inline AVLTreeNode* Root() const { return fRoot; }
|
||||||
|
|
||||||
|
AVLTreeNode* LeftMost(AVLTreeNode* node) const;
|
||||||
|
AVLTreeNode* RightMost(AVLTreeNode* node) const;
|
||||||
|
|
||||||
|
AVLTreeNode* Previous(AVLTreeNode* node) const;
|
||||||
|
AVLTreeNode* Next(AVLTreeNode* node) const;
|
||||||
|
|
||||||
|
inline AVLTreeIterator GetIterator() const;
|
||||||
|
inline AVLTreeIterator GetIterator(AVLTreeNode* node) const;
|
||||||
|
|
||||||
|
AVLTreeNode* Find(const void* key) const;
|
||||||
|
AVLTreeNode* FindClosest(const void* key, bool less) const;
|
||||||
|
|
||||||
|
status_t Insert(AVLTreeNode* element);
|
||||||
|
AVLTreeNode* Remove(const void* key);
|
||||||
|
bool Remove(AVLTreeNode* element);
|
||||||
|
|
||||||
|
void CheckTree() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
NOT_FOUND = -3,
|
||||||
|
DUPLICATE = -2,
|
||||||
|
NO_MEMORY = -1,
|
||||||
|
OK = 0,
|
||||||
|
HEIGHT_CHANGED = 1,
|
||||||
|
|
||||||
|
LEFT = -1,
|
||||||
|
BALANCED = 0,
|
||||||
|
RIGHT = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// rotations
|
||||||
|
void _RotateRight(AVLTreeNode** nodeP);
|
||||||
|
void _RotateLeft(AVLTreeNode** nodeP);
|
||||||
|
|
||||||
|
// insert
|
||||||
|
int _BalanceInsertLeft(AVLTreeNode** node);
|
||||||
|
int _BalanceInsertRight(AVLTreeNode** node);
|
||||||
|
int _Insert(AVLTreeNode* nodeToInsert);
|
||||||
|
|
||||||
|
// remove
|
||||||
|
int _BalanceRemoveLeft(AVLTreeNode** node);
|
||||||
|
int _BalanceRemoveRight(AVLTreeNode** node);
|
||||||
|
int _RemoveRightMostChild(AVLTreeNode** node,
|
||||||
|
AVLTreeNode** foundNode);
|
||||||
|
int _Remove(AVLTreeNode* node);
|
||||||
|
|
||||||
|
int _CheckTree(AVLTreeNode* parent,
|
||||||
|
AVLTreeNode* node, int& _nodeCount) const;
|
||||||
|
|
||||||
|
AVLTreeNode* fRoot;
|
||||||
|
int fNodeCount;
|
||||||
|
AVLTreeCompare* fCompare;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// AVLTreeIterator
|
||||||
|
class AVLTreeIterator {
|
||||||
|
public:
|
||||||
|
inline AVLTreeIterator()
|
||||||
|
:
|
||||||
|
fParent(NULL),
|
||||||
|
fCurrent(NULL),
|
||||||
|
fNext(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AVLTreeIterator(const AVLTreeIterator& other)
|
||||||
|
:
|
||||||
|
fParent(other.fParent),
|
||||||
|
fCurrent(other.fCurrent),
|
||||||
|
fNext(other.fNext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AVLTreeNode* Current() const
|
||||||
|
{
|
||||||
|
return fCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool HasNext() const
|
||||||
|
{
|
||||||
|
return fNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AVLTreeNode* Next()
|
||||||
|
{
|
||||||
|
fCurrent = fNext;
|
||||||
|
|
||||||
|
if (fNext)
|
||||||
|
fNext = fParent->Next(fNext);
|
||||||
|
|
||||||
|
return fCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AVLTreeNode* Previous()
|
||||||
|
{
|
||||||
|
if (fCurrent) {
|
||||||
|
fNext = fCurrent;
|
||||||
|
fCurrent = fParent->Previous(fCurrent);
|
||||||
|
} else if (fNext)
|
||||||
|
fCurrent = fParent->Previous(fNext);
|
||||||
|
|
||||||
|
return fCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AVLTreeNode* Remove()
|
||||||
|
{
|
||||||
|
if (!fCurrent)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
AVLTreeNode* node = fCurrent;
|
||||||
|
fCurrent = NULL;
|
||||||
|
|
||||||
|
return (const_cast<AVLTreeBase*>(fParent)->Remove(node) ? node : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AVLTreeIterator& operator=(const AVLTreeIterator& other)
|
||||||
|
{
|
||||||
|
fParent = other.fParent;
|
||||||
|
fCurrent = other.fCurrent;
|
||||||
|
fNext = other.fNext;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline AVLTreeIterator(const AVLTreeBase* parent, AVLTreeNode* current,
|
||||||
|
AVLTreeNode* next)
|
||||||
|
:
|
||||||
|
fParent(parent),
|
||||||
|
fCurrent(current),
|
||||||
|
fNext(next)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class AVLTreeBase;
|
||||||
|
|
||||||
|
const AVLTreeBase* fParent;
|
||||||
|
AVLTreeNode* fCurrent;
|
||||||
|
AVLTreeNode* fNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// GetIterator
|
||||||
|
inline AVLTreeIterator
|
||||||
|
AVLTreeBase::GetIterator() const
|
||||||
|
{
|
||||||
|
return AVLTreeIterator(this, NULL, LeftMost(fRoot));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GetIterator
|
||||||
|
inline AVLTreeIterator
|
||||||
|
AVLTreeBase::GetIterator(AVLTreeNode* node) const
|
||||||
|
{
|
||||||
|
return AVLTreeIterator(this, node, Next(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _KERNEL_UTIL_AVL_TREE_BASE_H
|
||||||
@@ -1,209 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007, Ingo Weinhold <[email protected].de>.
|
* Copyright 2003-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _AVL_TREE_MAP_H
|
#ifndef _KERNEL_UTIL_AVL_TREE_MAP_H
|
||||||
#define _AVL_TREE_MAP_H
|
#define _KERNEL_UTIL_AVL_TREE_MAP_H
|
||||||
|
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
#include <util/kernel_cpp.h>
|
|
||||||
|
|
||||||
#include <util/MallocFreeAllocator.h>
|
#include <util/MallocFreeAllocator.h>
|
||||||
|
#include <util/AVLTreeBase.h>
|
||||||
|
|
||||||
// maximal height of a tree
|
|
||||||
static const int kMaxAVLTreeHeight = 32;
|
|
||||||
|
|
||||||
class AVLTreeIterator;
|
|
||||||
|
|
||||||
|
|
||||||
// AVLTreeNode
|
|
||||||
struct AVLTreeNode {
|
|
||||||
AVLTreeNode* parent;
|
|
||||||
AVLTreeNode* left;
|
|
||||||
AVLTreeNode* right;
|
|
||||||
int balance_factor;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// AVLTreeCompare
|
|
||||||
class AVLTreeCompare {
|
|
||||||
public:
|
|
||||||
virtual ~AVLTreeCompare();
|
|
||||||
|
|
||||||
virtual int CompareKeyNode(const void* key,
|
|
||||||
const AVLTreeNode* node) = 0;
|
|
||||||
virtual int CompareNodes(const AVLTreeNode* node1,
|
|
||||||
const AVLTreeNode* node2) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// AVLTree
|
|
||||||
class AVLTree {
|
|
||||||
public:
|
|
||||||
AVLTree(AVLTreeCompare* compare);
|
|
||||||
~AVLTree();
|
|
||||||
|
|
||||||
inline int Count() const { return fNodeCount; }
|
|
||||||
inline bool IsEmpty() const { return (fNodeCount == 0); }
|
|
||||||
void MakeEmpty();
|
|
||||||
|
|
||||||
inline AVLTreeNode* Root() const { return fRoot; }
|
|
||||||
|
|
||||||
AVLTreeNode* LeftMost(AVLTreeNode* node) const;
|
|
||||||
AVLTreeNode* RightMost(AVLTreeNode* node) const;
|
|
||||||
|
|
||||||
AVLTreeNode* Previous(AVLTreeNode* node) const;
|
|
||||||
AVLTreeNode* Next(AVLTreeNode* node) const;
|
|
||||||
|
|
||||||
inline AVLTreeIterator GetIterator() const;
|
|
||||||
inline AVLTreeIterator GetIterator(AVLTreeNode* node) const;
|
|
||||||
|
|
||||||
AVLTreeNode* Find(const void* key);
|
|
||||||
AVLTreeNode* FindClose(const void* key, bool less);
|
|
||||||
|
|
||||||
status_t Insert(AVLTreeNode* element);
|
|
||||||
AVLTreeNode* Remove(const void* key);
|
|
||||||
bool Remove(AVLTreeNode* element);
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
NOT_FOUND = -3,
|
|
||||||
DUPLICATE = -2,
|
|
||||||
NO_MEMORY = -1,
|
|
||||||
OK = 0,
|
|
||||||
HEIGHT_CHANGED = 1,
|
|
||||||
|
|
||||||
LEFT = -1,
|
|
||||||
BALANCED = 0,
|
|
||||||
RIGHT = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// rotations
|
|
||||||
void _RotateRight(AVLTreeNode** nodeP);
|
|
||||||
void _RotateLeft(AVLTreeNode** nodeP);
|
|
||||||
|
|
||||||
// insert
|
|
||||||
int _BalanceInsertLeft(AVLTreeNode** node);
|
|
||||||
int _BalanceInsertRight(AVLTreeNode** node);
|
|
||||||
int _Insert(AVLTreeNode* nodeToInsert);
|
|
||||||
|
|
||||||
// remove
|
|
||||||
int _BalanceRemoveLeft(AVLTreeNode** node);
|
|
||||||
int _BalanceRemoveRight(AVLTreeNode** node);
|
|
||||||
int _RemoveRightMostChild(AVLTreeNode** node,
|
|
||||||
AVLTreeNode** foundNode);
|
|
||||||
int _Remove(AVLTreeNode* node);
|
|
||||||
|
|
||||||
AVLTreeNode* fRoot;
|
|
||||||
int fNodeCount;
|
|
||||||
AVLTreeCompare* fCompare;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// AVLTreeIterator
|
|
||||||
class AVLTreeIterator {
|
|
||||||
public:
|
|
||||||
inline AVLTreeIterator()
|
|
||||||
: fParent(NULL),
|
|
||||||
fCurrent(NULL),
|
|
||||||
fNext(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AVLTreeIterator(const AVLTreeIterator& other)
|
|
||||||
: fParent(other.fParent),
|
|
||||||
fCurrent(other.fCurrent),
|
|
||||||
fNext(other.fNext)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AVLTreeNode* Current() const
|
|
||||||
{
|
|
||||||
return fCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool HasNext() const
|
|
||||||
{
|
|
||||||
return fNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AVLTreeNode* Next()
|
|
||||||
{
|
|
||||||
fCurrent = fNext;
|
|
||||||
|
|
||||||
if (fNext)
|
|
||||||
fNext = fParent->Next(fNext);
|
|
||||||
|
|
||||||
return fCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AVLTreeNode* Previous()
|
|
||||||
{
|
|
||||||
if (fCurrent) {
|
|
||||||
fNext = fCurrent;
|
|
||||||
fCurrent = fParent->Previous(fCurrent);
|
|
||||||
} else if (fNext)
|
|
||||||
fCurrent = fParent->Previous(fNext);
|
|
||||||
|
|
||||||
return fCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AVLTreeNode* Remove()
|
|
||||||
{
|
|
||||||
if (!fCurrent)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
AVLTreeNode* node = fCurrent;
|
|
||||||
fCurrent = NULL;
|
|
||||||
|
|
||||||
return (const_cast<AVLTree*>(fParent)->Remove(node) ? node : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline AVLTreeIterator& operator=(const AVLTreeIterator& other)
|
|
||||||
{
|
|
||||||
fParent = other.fParent;
|
|
||||||
fCurrent = other.fCurrent;
|
|
||||||
fNext = other.fNext;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline AVLTreeIterator(const AVLTree* parent, AVLTreeNode* current,
|
|
||||||
AVLTreeNode* next)
|
|
||||||
: fParent(parent),
|
|
||||||
fCurrent(current),
|
|
||||||
fNext(next)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class AVLTree;
|
|
||||||
|
|
||||||
const AVLTree* fParent;
|
|
||||||
AVLTreeNode* fCurrent;
|
|
||||||
AVLTreeNode* fNext;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// GetIterator
|
|
||||||
inline AVLTreeIterator
|
|
||||||
AVLTree::GetIterator() const
|
|
||||||
{
|
|
||||||
return AVLTreeIterator(this, NULL, LeftMost(fRoot));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// GetIterator
|
|
||||||
inline AVLTreeIterator
|
|
||||||
AVLTree::GetIterator(AVLTreeNode* node) const
|
|
||||||
{
|
|
||||||
return AVLTreeIterator(this, node, Next(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - AVLTreeMap and friends
|
|
||||||
|
|
||||||
|
|
||||||
// strategies
|
// strategies
|
||||||
@@ -299,7 +103,7 @@ protected:
|
|||||||
friend class Iterator;
|
friend class Iterator;
|
||||||
friend class ConstIterator;
|
friend class ConstIterator;
|
||||||
|
|
||||||
AVLTree fTree;
|
AVLTreeBase fTree;
|
||||||
NodeStrategy fStrategy;
|
NodeStrategy fStrategy;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -518,7 +322,7 @@ _AVL_TREE_MAP_TEMPLATE_LIST
|
|||||||
typename _AVL_TREE_MAP_CLASS_NAME::Iterator
|
typename _AVL_TREE_MAP_CLASS_NAME::Iterator
|
||||||
_AVL_TREE_MAP_CLASS_NAME::FindClose(const Key& key, bool less)
|
_AVL_TREE_MAP_CLASS_NAME::FindClose(const Key& key, bool less)
|
||||||
{
|
{
|
||||||
if (AVLTreeNode* node = fTree.FindClose(&key, less))
|
if (AVLTreeNode* node = fTree.FindClosest(&key, less))
|
||||||
return Iterator(this, fTree.GetIterator(node));
|
return Iterator(this, fTree.GetIterator(node));
|
||||||
return Iterator();
|
return Iterator();
|
||||||
}
|
}
|
||||||
@@ -776,4 +580,4 @@ private:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _AVL_TREE_MAP_H
|
#endif // _KERNEL_UTIL_AVL_TREE_MAP_H
|
||||||
|
|||||||
@@ -1,9 +1,32 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
* Copyright 2003-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <util/AVLTreeMap.h>
|
|
||||||
|
#include <util/AVLTreeBase.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _KERNEL_MODE
|
||||||
|
# define CHECK_FAILED(message...) panic(message)
|
||||||
|
#else
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <OS.h>
|
||||||
|
# define CHECK_FAILED(message...) \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr, message); \
|
||||||
|
fprintf(stderr, "\n"); \
|
||||||
|
debugger("AVLTreeBase check failed"); \
|
||||||
|
} while (false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// maximal height of a tree
|
||||||
|
static const int kMaxAVLTreeHeight = 32;
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - AVLTreeCompare
|
// #pragma mark - AVLTreeCompare
|
||||||
@@ -14,10 +37,10 @@ AVLTreeCompare::~AVLTreeCompare()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - AVLTree
|
// #pragma mark - AVLTreeBase
|
||||||
|
|
||||||
|
|
||||||
AVLTree::AVLTree(AVLTreeCompare* compare)
|
AVLTreeBase::AVLTreeBase(AVLTreeCompare* compare)
|
||||||
: fRoot(NULL),
|
: fRoot(NULL),
|
||||||
fNodeCount(0),
|
fNodeCount(0),
|
||||||
fCompare(compare)
|
fCompare(compare)
|
||||||
@@ -25,77 +48,21 @@ AVLTree::AVLTree(AVLTreeCompare* compare)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AVLTree::~AVLTree()
|
AVLTreeBase::~AVLTreeBase()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AVLTree::MakeEmpty()
|
AVLTreeBase::MakeEmpty()
|
||||||
{
|
{
|
||||||
fRoot = NULL;
|
fRoot = NULL;
|
||||||
fNodeCount = 0;
|
fNodeCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
AVLTree::Insert(AVLTreeNode* nodeToInsert)
|
|
||||||
{
|
|
||||||
int result = _Insert(nodeToInsert);
|
|
||||||
switch (result) {
|
|
||||||
case OK:
|
|
||||||
case HEIGHT_CHANGED:
|
|
||||||
return B_OK;
|
|
||||||
case NO_MEMORY:
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
case DUPLICATE:
|
|
||||||
default:
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
AVLTreeNode*
|
||||||
AVLTree::Remove(const void* key)
|
AVLTreeBase::LeftMost(AVLTreeNode* node) const
|
||||||
{
|
|
||||||
// find node
|
|
||||||
AVLTreeNode* node = fRoot;
|
|
||||||
while (node) {
|
|
||||||
int cmp = fCompare->CompareKeyNode(key, node);
|
|
||||||
if (cmp == 0)
|
|
||||||
break;
|
|
||||||
else {
|
|
||||||
if (cmp < 0)
|
|
||||||
node = node->left;
|
|
||||||
else
|
|
||||||
node = node->right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove it
|
|
||||||
if (node)
|
|
||||||
_Remove(node);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
AVLTree::Remove(AVLTreeNode* node)
|
|
||||||
{
|
|
||||||
switch (_Remove(node)) {
|
|
||||||
case OK:
|
|
||||||
case HEIGHT_CHANGED:
|
|
||||||
return true;
|
|
||||||
case NOT_FOUND:
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
|
||||||
AVLTree::LeftMost(AVLTreeNode* node) const
|
|
||||||
{
|
{
|
||||||
if (node) {
|
if (node) {
|
||||||
while (node->left)
|
while (node->left)
|
||||||
@@ -107,7 +74,7 @@ AVLTree::LeftMost(AVLTreeNode* node) const
|
|||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
AVLTreeNode*
|
||||||
AVLTree::RightMost(AVLTreeNode* node) const
|
AVLTreeBase::RightMost(AVLTreeNode* node) const
|
||||||
{
|
{
|
||||||
if (node) {
|
if (node) {
|
||||||
while (node->right)
|
while (node->right)
|
||||||
@@ -119,7 +86,7 @@ AVLTree::RightMost(AVLTreeNode* node) const
|
|||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
AVLTreeNode*
|
||||||
AVLTree::Previous(AVLTreeNode* node) const
|
AVLTreeBase::Previous(AVLTreeNode* node) const
|
||||||
{
|
{
|
||||||
if (node) {
|
if (node) {
|
||||||
// The previous node cannot be in the right subtree.
|
// The previous node cannot be in the right subtree.
|
||||||
@@ -144,7 +111,7 @@ AVLTree::Previous(AVLTreeNode* node) const
|
|||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
AVLTreeNode*
|
||||||
AVLTree::Next(AVLTreeNode* node) const
|
AVLTreeBase::Next(AVLTreeNode* node) const
|
||||||
{
|
{
|
||||||
if (node) {
|
if (node) {
|
||||||
// The next node cannot be in the left subtree.
|
// The next node cannot be in the left subtree.
|
||||||
@@ -169,7 +136,7 @@ AVLTree::Next(AVLTreeNode* node) const
|
|||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
AVLTreeNode*
|
||||||
AVLTree::Find(const void* key)
|
AVLTreeBase::Find(const void* key) const
|
||||||
{
|
{
|
||||||
AVLTreeNode* node = fRoot;
|
AVLTreeNode* node = fRoot;
|
||||||
|
|
||||||
@@ -189,7 +156,7 @@ AVLTree::Find(const void* key)
|
|||||||
|
|
||||||
|
|
||||||
AVLTreeNode*
|
AVLTreeNode*
|
||||||
AVLTree::FindClose(const void* key, bool less)
|
AVLTreeBase::FindClosest(const void* key, bool less) const
|
||||||
{
|
{
|
||||||
AVLTreeNode* node = fRoot;
|
AVLTreeNode* node = fRoot;
|
||||||
AVLTreeNode* parent = NULL;
|
AVLTreeNode* parent = NULL;
|
||||||
@@ -225,8 +192,76 @@ AVLTree::FindClose(const void* key, bool less)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AVLTreeBase::Insert(AVLTreeNode* nodeToInsert)
|
||||||
|
{
|
||||||
|
int result = _Insert(nodeToInsert);
|
||||||
|
switch (result) {
|
||||||
|
case OK:
|
||||||
|
case HEIGHT_CHANGED:
|
||||||
|
return B_OK;
|
||||||
|
case NO_MEMORY:
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
case DUPLICATE:
|
||||||
|
default:
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AVLTreeNode*
|
||||||
|
AVLTreeBase::Remove(const void* key)
|
||||||
|
{
|
||||||
|
// find node
|
||||||
|
AVLTreeNode* node = fRoot;
|
||||||
|
while (node) {
|
||||||
|
int cmp = fCompare->CompareKeyNode(key, node);
|
||||||
|
if (cmp == 0)
|
||||||
|
break;
|
||||||
|
else {
|
||||||
|
if (cmp < 0)
|
||||||
|
node = node->left;
|
||||||
|
else
|
||||||
|
node = node->right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove it
|
||||||
|
if (node)
|
||||||
|
_Remove(node);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AVLTreeBase::Remove(AVLTreeNode* node)
|
||||||
|
{
|
||||||
|
switch (_Remove(node)) {
|
||||||
|
case OK:
|
||||||
|
case HEIGHT_CHANGED:
|
||||||
|
return true;
|
||||||
|
case NOT_FOUND:
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AVLTree::_RotateRight(AVLTreeNode** nodeP)
|
AVLTreeBase::CheckTree() const
|
||||||
|
{
|
||||||
|
int nodeCount = 0;
|
||||||
|
_CheckTree(NULL, fRoot, nodeCount);
|
||||||
|
if (nodeCount != fNodeCount) {
|
||||||
|
CHECK_FAILED("AVLTreeBase::CheckTree(): node count mismatch: %d vs %d",
|
||||||
|
nodeCount, fNodeCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AVLTreeBase::_RotateRight(AVLTreeNode** nodeP)
|
||||||
{
|
{
|
||||||
// rotate the nodes
|
// rotate the nodes
|
||||||
AVLTreeNode* node = *nodeP;
|
AVLTreeNode* node = *nodeP;
|
||||||
@@ -257,7 +292,7 @@ AVLTree::_RotateRight(AVLTreeNode** nodeP)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AVLTree::_RotateLeft(AVLTreeNode** nodeP)
|
AVLTreeBase::_RotateLeft(AVLTreeNode** nodeP)
|
||||||
{
|
{
|
||||||
// rotate the nodes
|
// rotate the nodes
|
||||||
AVLTreeNode* node = *nodeP;
|
AVLTreeNode* node = *nodeP;
|
||||||
@@ -288,7 +323,7 @@ AVLTree::_RotateLeft(AVLTreeNode** nodeP)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_BalanceInsertLeft(AVLTreeNode** node)
|
AVLTreeBase::_BalanceInsertLeft(AVLTreeNode** node)
|
||||||
{
|
{
|
||||||
if ((*node)->balance_factor < LEFT) {
|
if ((*node)->balance_factor < LEFT) {
|
||||||
// tree is left heavy
|
// tree is left heavy
|
||||||
@@ -312,7 +347,7 @@ AVLTree::_BalanceInsertLeft(AVLTreeNode** node)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_BalanceInsertRight(AVLTreeNode** node)
|
AVLTreeBase::_BalanceInsertRight(AVLTreeNode** node)
|
||||||
{
|
{
|
||||||
if ((*node)->balance_factor > RIGHT) {
|
if ((*node)->balance_factor > RIGHT) {
|
||||||
// tree is right heavy
|
// tree is right heavy
|
||||||
@@ -336,7 +371,7 @@ AVLTree::_BalanceInsertRight(AVLTreeNode** node)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_Insert(AVLTreeNode* nodeToInsert)
|
AVLTreeBase::_Insert(AVLTreeNode* nodeToInsert)
|
||||||
{
|
{
|
||||||
struct node_info {
|
struct node_info {
|
||||||
AVLTreeNode** node;
|
AVLTreeNode** node;
|
||||||
@@ -378,10 +413,6 @@ AVLTree::_Insert(AVLTreeNode* nodeToInsert)
|
|||||||
else
|
else
|
||||||
(*node)->parent = *top[-1].node;
|
(*node)->parent = *top[-1].node;
|
||||||
|
|
||||||
// init the iterator
|
|
||||||
// if (iterator)
|
|
||||||
// *iterator = Iterator(this, *node);
|
|
||||||
|
|
||||||
// do the balancing
|
// do the balancing
|
||||||
int result = HEIGHT_CHANGED;
|
int result = HEIGHT_CHANGED;
|
||||||
while (result == HEIGHT_CHANGED && top != bottom) {
|
while (result == HEIGHT_CHANGED && top != bottom) {
|
||||||
@@ -403,7 +434,7 @@ AVLTree::_Insert(AVLTreeNode* nodeToInsert)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_BalanceRemoveLeft(AVLTreeNode** node)
|
AVLTreeBase::_BalanceRemoveLeft(AVLTreeNode** node)
|
||||||
{
|
{
|
||||||
int result = HEIGHT_CHANGED;
|
int result = HEIGHT_CHANGED;
|
||||||
|
|
||||||
@@ -430,7 +461,7 @@ AVLTree::_BalanceRemoveLeft(AVLTreeNode** node)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_BalanceRemoveRight(AVLTreeNode** node)
|
AVLTreeBase::_BalanceRemoveRight(AVLTreeNode** node)
|
||||||
{
|
{
|
||||||
int result = HEIGHT_CHANGED;
|
int result = HEIGHT_CHANGED;
|
||||||
|
|
||||||
@@ -457,7 +488,7 @@ AVLTree::_BalanceRemoveRight(AVLTreeNode** node)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_RemoveRightMostChild(AVLTreeNode** node, AVLTreeNode** foundNode)
|
AVLTreeBase::_RemoveRightMostChild(AVLTreeNode** node, AVLTreeNode** foundNode)
|
||||||
{
|
{
|
||||||
AVLTreeNode** stack[kMaxAVLTreeHeight];
|
AVLTreeNode** stack[kMaxAVLTreeHeight];
|
||||||
AVLTreeNode*** top = stack;
|
AVLTreeNode*** top = stack;
|
||||||
@@ -495,7 +526,7 @@ AVLTree::_RemoveRightMostChild(AVLTreeNode** node, AVLTreeNode** foundNode)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AVLTree::_Remove(AVLTreeNode* node)
|
AVLTreeBase::_Remove(AVLTreeNode* node)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return NOT_FOUND;
|
return NOT_FOUND;
|
||||||
@@ -563,3 +594,36 @@ AVLTree::_Remove(AVLTreeNode* node)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
AVLTreeBase::_CheckTree(AVLTreeNode* parent, AVLTreeNode* node,
|
||||||
|
int& _nodeCount) const
|
||||||
|
{
|
||||||
|
if (node == NULL) {
|
||||||
|
_nodeCount = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent != node->parent) {
|
||||||
|
CHECK_FAILED("AVLTreeBase::_CheckTree(): node %p parent mismatch: "
|
||||||
|
"%p vs %p", node, parent, node->parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int leftNodeCount;
|
||||||
|
int leftDepth = _CheckTree(node, node->left, leftNodeCount);
|
||||||
|
|
||||||
|
int rightNodeCount;
|
||||||
|
int rightDepth = _CheckTree(node, node->right, rightNodeCount);
|
||||||
|
|
||||||
|
int balance = rightDepth - leftDepth;
|
||||||
|
if (balance < LEFT || balance > RIGHT) {
|
||||||
|
CHECK_FAILED("AVLTreeBase::_CheckTree(): unbalanced subtree: %p", node);
|
||||||
|
} else if (balance != node->balance_factor) {
|
||||||
|
CHECK_FAILED("AVLTreeBase::_CheckTree(): subtree %p balance mismatch: "
|
||||||
|
"%d vs %d", node, balance, node->balance_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
_nodeCount = leftNodeCount + rightNodeCount + 1;
|
||||||
|
return std::max(leftDepth, rightDepth) + 1;
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ SubDir HAIKU_TOP src system kernel util ;
|
|||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
KernelMergeObject kernel_util.o :
|
KernelMergeObject kernel_util.o :
|
||||||
AVLTreeMap.cpp
|
AVLTreeBase.cpp
|
||||||
kernel_cpp.cpp
|
kernel_cpp.cpp
|
||||||
khash.cpp
|
khash.cpp
|
||||||
list.cpp
|
list.cpp
|
||||||
|
|||||||
Reference in New Issue
Block a user