mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Added tree traversal routines for tree data structures.
svn path=/trunk/; revision=2774
This commit is contained in:
parent
aea2b71437
commit
9ab896569c
6 changed files with 389 additions and 23 deletions
|
@ -845,6 +845,12 @@ ExRemoveBinaryTree(IN PBINARY_TREE Tree,
|
||||||
IN PVOID Key,
|
IN PVOID Key,
|
||||||
IN PVOID * Value);
|
IN PVOID * Value);
|
||||||
|
|
||||||
|
BOOLEAN STDCALL
|
||||||
|
ExTraverseBinaryTree(IN PBINARY_TREE Tree,
|
||||||
|
IN TRAVERSE_METHOD Method,
|
||||||
|
IN PTRAVERSE_ROUTINE Routine,
|
||||||
|
IN PVOID Context);
|
||||||
|
|
||||||
BOOLEAN STDCALL
|
BOOLEAN STDCALL
|
||||||
ExInitializeSplayTree(IN PSPLAY_TREE Tree,
|
ExInitializeSplayTree(IN PSPLAY_TREE Tree,
|
||||||
IN PKEY_COMPARATOR Compare,
|
IN PKEY_COMPARATOR Compare,
|
||||||
|
@ -873,6 +879,12 @@ BOOLEAN STDCALL
|
||||||
ExWeightOfSplayTree(IN PSPLAY_TREE Tree,
|
ExWeightOfSplayTree(IN PSPLAY_TREE Tree,
|
||||||
OUT PULONG Weight);
|
OUT PULONG Weight);
|
||||||
|
|
||||||
|
BOOLEAN STDCALL
|
||||||
|
ExTraverseSplayTree(IN PSPLAY_TREE Tree,
|
||||||
|
IN TRAVERSE_METHOD Method,
|
||||||
|
IN PTRAVERSE_ROUTINE Routine,
|
||||||
|
IN PVOID Context);
|
||||||
|
|
||||||
BOOLEAN STDCALL
|
BOOLEAN STDCALL
|
||||||
ExInitializeHashTable(IN PHASH_TABLE HashTable,
|
ExInitializeHashTable(IN PHASH_TABLE HashTable,
|
||||||
IN ULONG HashTableSize,
|
IN ULONG HashTableSize,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: extypes.h,v 1.8 2002/03/23 13:53:21 chorns Exp $ */
|
/* $Id: extypes.h,v 1.9 2002/03/23 19:44:45 chorns Exp $ */
|
||||||
|
|
||||||
#ifndef __INCLUDE_DDK_EXTYPES_H
|
#ifndef __INCLUDE_DDK_EXTYPES_H
|
||||||
#define __INCLUDE_DDK_EXTYPES_H
|
#define __INCLUDE_DDK_EXTYPES_H
|
||||||
|
@ -160,8 +160,20 @@ typedef VOID STDCALL
|
||||||
|
|
||||||
/* BEGIN REACTOS ONLY */
|
/* BEGIN REACTOS ONLY */
|
||||||
|
|
||||||
typedef LONG STDCALL (*PKEY_COMPARATOR)(PVOID Key1,
|
typedef enum _TRAVERSE_METHOD {
|
||||||
PVOID Key2);
|
TraverseMethodPreorder,
|
||||||
|
TraverseMethodInorder,
|
||||||
|
TraverseMethodPostorder
|
||||||
|
} TRAVERSE_METHOD;
|
||||||
|
|
||||||
|
typedef LONG STDCALL
|
||||||
|
(*PKEY_COMPARATOR)(IN PVOID Key1,
|
||||||
|
IN PVOID Key2);
|
||||||
|
|
||||||
|
typedef BOOLEAN STDCALL
|
||||||
|
(*PTRAVERSE_ROUTINE)(IN PVOID Context,
|
||||||
|
IN PVOID Key,
|
||||||
|
IN PVOID Value);
|
||||||
|
|
||||||
struct _BINARY_TREE_NODE;
|
struct _BINARY_TREE_NODE;
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,16 @@ typedef struct _BINARY_TREE_NODE
|
||||||
PVOID Value;
|
PVOID Value;
|
||||||
} BINARY_TREE_NODE, *PBINARY_TREE_NODE;
|
} BINARY_TREE_NODE, *PBINARY_TREE_NODE;
|
||||||
|
|
||||||
|
typedef struct _TRAVERSE_CONTEXT {
|
||||||
|
PTRAVERSE_ROUTINE Routine;
|
||||||
|
PVOID Context;
|
||||||
|
} TRAVERSE_CONTEXT, *PTRAVERSE_CONTEXT;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
#define ExpBinaryTreeRootNode(Tree)(((PBINARY_TREE) (Tree))->RootNode)
|
#define ExpBinaryTreeRootNode(Tree)(((PBINARY_TREE) (Tree))->RootNode)
|
||||||
#define ExpIsExternalBinaryTreeNode(Node)(((Node)->LeftChild == NULL) && ((Node)->RightChild == NULL))
|
#define ExpBinaryTreeIsExternalNode(Node)(((Node)->LeftChild == NULL) && ((Node)->RightChild == NULL))
|
||||||
#define ExpIsInternalBinaryTreeNode(Node)(!ExpIsExternalBinaryTreeNode(Node))
|
#define ExpBinaryTreeIsInternalNode(Node)(!ExpBinaryTreeIsExternalNode(Node))
|
||||||
#define ExpBinaryTreeNodeKey(Node)((Node)->Key)
|
#define ExpBinaryTreeNodeKey(Node)((Node)->Key)
|
||||||
#define ExpBinaryTreeNodeValue(Node)((Node)->Value)
|
#define ExpBinaryTreeNodeValue(Node)((Node)->Value)
|
||||||
#define ExpBinaryTreeParentNode(Node)((Node)->Parent)
|
#define ExpBinaryTreeParentNode(Node)((Node)->Parent)
|
||||||
|
@ -228,7 +233,7 @@ ExpSearchBinaryTree(PBINARY_TREE Tree,
|
||||||
|
|
||||||
/* FIXME: Possibly do this iteratively due to the small kernel-mode stack */
|
/* FIXME: Possibly do this iteratively due to the small kernel-mode stack */
|
||||||
|
|
||||||
if (ExpIsExternalBinaryTreeNode(Node))
|
if (ExpBinaryTreeIsExternalNode(Node))
|
||||||
{
|
{
|
||||||
return Node;
|
return Node;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +265,7 @@ VOID
|
||||||
ExpRemoveAboveExternalBinaryTreeNode(PBINARY_TREE Tree,
|
ExpRemoveAboveExternalBinaryTreeNode(PBINARY_TREE Tree,
|
||||||
PBINARY_TREE_NODE Node)
|
PBINARY_TREE_NODE Node)
|
||||||
{
|
{
|
||||||
assertmsg(ExpIsExternalBinaryTreeNode(Node), ("Node is not external"));
|
assertmsg(ExpBinaryTreeIsExternalNode(Node), ("Node is not external"));
|
||||||
|
|
||||||
if (Node == ExpBinaryTreeRootNode(Tree))
|
if (Node == ExpBinaryTreeRootNode(Tree))
|
||||||
{
|
{
|
||||||
|
@ -294,7 +299,7 @@ ExpDeleteBinaryTree(PBINARY_TREE Tree,
|
||||||
{
|
{
|
||||||
/* FIXME: Possibly do this iteratively due to the small kernel-mode stack */
|
/* FIXME: Possibly do this iteratively due to the small kernel-mode stack */
|
||||||
|
|
||||||
if (ExpIsInternalBinaryTreeNode(Node))
|
if (ExpBinaryTreeIsInternalNode(Node))
|
||||||
{
|
{
|
||||||
ExpDeleteBinaryTree(Tree, ExpBinaryTreeLeftChildNode(Node));
|
ExpDeleteBinaryTree(Tree, ExpBinaryTreeLeftChildNode(Node));
|
||||||
ExpDeleteBinaryTree(Tree, ExpBinaryTreeRightChildNode(Node));
|
ExpDeleteBinaryTree(Tree, ExpBinaryTreeRightChildNode(Node));
|
||||||
|
@ -304,6 +309,99 @@ ExpDeleteBinaryTree(PBINARY_TREE Tree,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a binary tree using preorder traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpTraverseBinaryTreePreorder(PTRAVERSE_CONTEXT Context,
|
||||||
|
PBINARY_TREE_NODE Node)
|
||||||
|
{
|
||||||
|
if (ExpBinaryTreeIsInternalNode(Node))
|
||||||
|
{
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpBinaryTreeNodeKey(Node),
|
||||||
|
ExpBinaryTreeNodeValue(Node)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse left subtree */
|
||||||
|
ExpTraverseBinaryTreePreorder(Context, ExpBinaryTreeLeftChildNode(Node));
|
||||||
|
|
||||||
|
/* Traverse right subtree */
|
||||||
|
ExpTraverseBinaryTreePreorder(Context, ExpBinaryTreeRightChildNode(Node));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a binary tree using inorder traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpTraverseBinaryTreeInorder(PTRAVERSE_CONTEXT Context,
|
||||||
|
PBINARY_TREE_NODE Node)
|
||||||
|
{
|
||||||
|
if (ExpBinaryTreeIsInternalNode(Node))
|
||||||
|
{
|
||||||
|
/* Traverse left subtree */
|
||||||
|
ExpTraverseBinaryTreeInorder(Context, ExpBinaryTreeLeftChildNode(Node));
|
||||||
|
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpBinaryTreeNodeKey(Node),
|
||||||
|
ExpBinaryTreeNodeValue(Node)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse right subtree */
|
||||||
|
ExpTraverseBinaryTreeInorder(Context, ExpBinaryTreeRightChildNode(Node));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a binary tree using postorder traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpTraverseBinaryTreePostorder(PTRAVERSE_CONTEXT Context,
|
||||||
|
PBINARY_TREE_NODE Node)
|
||||||
|
{
|
||||||
|
if (ExpBinaryTreeIsInternalNode(Node))
|
||||||
|
{
|
||||||
|
/* Traverse left subtree */
|
||||||
|
ExpTraverseBinaryTreePostorder(Context, ExpBinaryTreeLeftChildNode(Node));
|
||||||
|
|
||||||
|
/* Traverse right subtree */
|
||||||
|
ExpTraverseBinaryTreePostorder(Context, ExpBinaryTreeRightChildNode(Node));
|
||||||
|
|
||||||
|
/* Call the traversal routine */
|
||||||
|
return (*Context->Routine)(Context->Context,
|
||||||
|
ExpBinaryTreeNodeKey(Node),
|
||||||
|
ExpBinaryTreeNodeValue(Node));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default key compare function. Compares the integer values of the two keys.
|
* Default key compare function. Compares the integer values of the two keys.
|
||||||
*/
|
*/
|
||||||
|
@ -420,7 +518,7 @@ ExInsertBinaryTree(IN PBINARY_TREE Tree,
|
||||||
{
|
{
|
||||||
Node = ExpSearchBinaryTree(Tree, Key, Node);
|
Node = ExpSearchBinaryTree(Tree, Key, Node);
|
||||||
|
|
||||||
if (ExpIsExternalBinaryTreeNode(Node))
|
if (ExpBinaryTreeIsExternalNode(Node))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +548,7 @@ ExSearchBinaryTree(IN PBINARY_TREE Tree,
|
||||||
ExpLockBinaryTree(Tree, &OldIrql);
|
ExpLockBinaryTree(Tree, &OldIrql);
|
||||||
Node = ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRootNode(Tree));
|
Node = ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRootNode(Tree));
|
||||||
|
|
||||||
if (ExpIsInternalBinaryTreeNode(Node))
|
if (ExpBinaryTreeIsInternalNode(Node))
|
||||||
{
|
{
|
||||||
*Value = ExpBinaryTreeNodeValue(Node);
|
*Value = ExpBinaryTreeNodeValue(Node);
|
||||||
ExpUnlockBinaryTree(Tree, &OldIrql);
|
ExpUnlockBinaryTree(Tree, &OldIrql);
|
||||||
|
@ -479,7 +577,7 @@ ExRemoveBinaryTree(IN PBINARY_TREE Tree,
|
||||||
|
|
||||||
Node = ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRootNode(Tree));
|
Node = ExpSearchBinaryTree(Tree, Key, ExpBinaryTreeRootNode(Tree));
|
||||||
|
|
||||||
if (ExpIsExternalBinaryTreeNode(Node))
|
if (ExpBinaryTreeIsExternalNode(Node))
|
||||||
{
|
{
|
||||||
ExpUnlockBinaryTree(Tree, &OldIrql);
|
ExpUnlockBinaryTree(Tree, &OldIrql);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -487,11 +585,11 @@ ExRemoveBinaryTree(IN PBINARY_TREE Tree,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*Value = ExpBinaryTreeNodeValue(Node);
|
*Value = ExpBinaryTreeNodeValue(Node);
|
||||||
if (ExpIsExternalBinaryTreeNode(ExpBinaryTreeLeftChildNode(Node)))
|
if (ExpBinaryTreeIsExternalNode(ExpBinaryTreeLeftChildNode(Node)))
|
||||||
{
|
{
|
||||||
Node = ExpBinaryTreeLeftChildNode(Node);
|
Node = ExpBinaryTreeLeftChildNode(Node);
|
||||||
}
|
}
|
||||||
else if (ExpIsExternalBinaryTreeNode(ExpBinaryTreeRightChildNode(Node)))
|
else if (ExpBinaryTreeIsExternalNode(ExpBinaryTreeRightChildNode(Node)))
|
||||||
{
|
{
|
||||||
Node = ExpBinaryTreeRightChildNode(Node);
|
Node = ExpBinaryTreeRightChildNode(Node);
|
||||||
}
|
}
|
||||||
|
@ -505,7 +603,7 @@ ExRemoveBinaryTree(IN PBINARY_TREE Tree,
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Node = ExpBinaryTreeLeftChildNode(Node);
|
Node = ExpBinaryTreeLeftChildNode(Node);
|
||||||
} while (ExpIsInternalBinaryTreeNode(Node));
|
} while (ExpBinaryTreeIsInternalNode(Node));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpRemoveAboveExternalBinaryTreeNode(Tree, Node);
|
ExpRemoveAboveExternalBinaryTreeNode(Tree, Node);
|
||||||
|
@ -514,4 +612,51 @@ ExRemoveBinaryTree(IN PBINARY_TREE Tree,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a binary tree using either preorder, inorder or postorder
|
||||||
|
* traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
*/
|
||||||
|
BOOLEAN STDCALL
|
||||||
|
ExTraverseBinaryTree(IN PBINARY_TREE Tree,
|
||||||
|
IN TRAVERSE_METHOD Method,
|
||||||
|
IN PTRAVERSE_ROUTINE Routine,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
TRAVERSE_CONTEXT tc;
|
||||||
|
BOOLEAN Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
tc.Routine = Routine;
|
||||||
|
tc.Context = Context;
|
||||||
|
|
||||||
|
ExpLockBinaryTree(Tree, &OldIrql);
|
||||||
|
|
||||||
|
switch (Method)
|
||||||
|
{
|
||||||
|
case TraverseMethodPreorder:
|
||||||
|
Status = ExpTraverseBinaryTreePreorder(&tc, ExpBinaryTreeRootNode(Tree));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TraverseMethodInorder:
|
||||||
|
Status = ExpTraverseBinaryTreeInorder(&tc, ExpBinaryTreeRootNode(Tree));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TraverseMethodPostorder:
|
||||||
|
Status = ExpTraverseBinaryTreePostorder(&tc, ExpBinaryTreeRootNode(Tree));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpUnlockBinaryTree(Tree, &OldIrql);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -40,10 +40,10 @@
|
||||||
|
|
||||||
typedef struct _SPLAY_TREE_NODE
|
typedef struct _SPLAY_TREE_NODE
|
||||||
{
|
{
|
||||||
/* Children on this branch has smaller keys than this node */
|
/* Children on this branch that has smaller keys than this node */
|
||||||
struct _SPLAY_TREE_NODE * SmallerChild;
|
struct _SPLAY_TREE_NODE * SmallerChild;
|
||||||
|
|
||||||
/* Children on this branch has larger keys than this node */
|
/* Children on this branch that has larger keys than this node */
|
||||||
struct _SPLAY_TREE_NODE * LargerChild;
|
struct _SPLAY_TREE_NODE * LargerChild;
|
||||||
|
|
||||||
/* Points to a node with identical key */
|
/* Points to a node with identical key */
|
||||||
|
@ -59,6 +59,11 @@ typedef struct _SPLAY_TREE_NODE
|
||||||
LONG Weight;
|
LONG Weight;
|
||||||
} SPLAY_TREE_NODE, *PSPLAY_TREE_NODE;
|
} SPLAY_TREE_NODE, *PSPLAY_TREE_NODE;
|
||||||
|
|
||||||
|
typedef struct _TRAVERSE_CONTEXT {
|
||||||
|
PTRAVERSE_ROUTINE Routine;
|
||||||
|
PVOID Context;
|
||||||
|
} TRAVERSE_CONTEXT, *PTRAVERSE_CONTEXT;
|
||||||
|
|
||||||
#define SPLAY_INDEX 0
|
#define SPLAY_INDEX 0
|
||||||
#define SEARCH_INDEX 1
|
#define SEARCH_INDEX 1
|
||||||
#define INSERT_INDEX 2
|
#define INSERT_INDEX 2
|
||||||
|
@ -185,7 +190,7 @@ ExpDestroySplayTreeNode(PSPLAY_TREE Tree,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Splay using the key 'Key' (which may or may not be in the tree). The starting
|
* Splay using the key 'Key' (which may or may not be in the tree). The starting
|
||||||
* root is Node. Weight fields are maintained.
|
* root is Node.
|
||||||
* The lock for the tree must be acquired when this routine is called.
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
* This routine does not maintain weight information.
|
* This routine does not maintain weight information.
|
||||||
*/
|
*/
|
||||||
|
@ -275,7 +280,7 @@ ExpSplayTreeNoWeight(PSPLAY_TREE Tree,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Splay using the key 'Key' (which may or may not be in the tree). The starting
|
* Splay using the key 'Key' (which may or may not be in the tree). The starting
|
||||||
* root is Node. Weight fields are maintained.
|
* root is Node.
|
||||||
* The lock for the tree must be acquired when this routine is called.
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
* This routine maintains weight information.
|
* This routine maintains weight information.
|
||||||
*/
|
*/
|
||||||
|
@ -943,6 +948,141 @@ ExpSplayTreeMaxTreeWeight(PSPLAY_TREE Tree,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a splay tree using preorder traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpTraverseSplayTreePreorder(PTRAVERSE_CONTEXT Context,
|
||||||
|
PSPLAY_TREE_NODE Node)
|
||||||
|
{
|
||||||
|
PSPLAY_TREE_NODE n;
|
||||||
|
|
||||||
|
if (Node == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpSplayTreeNodeKey(Node),
|
||||||
|
ExpSplayTreeNodeValue(Node)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
|
||||||
|
{
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpSplayTreeNodeKey(n),
|
||||||
|
ExpSplayTreeNodeValue(n)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse 'smaller' subtree */
|
||||||
|
ExpTraverseSplayTreePreorder(Context, ExpSplayTreeSmallerChildNode(Node));
|
||||||
|
|
||||||
|
/* Traverse 'larger' subtree */
|
||||||
|
ExpTraverseSplayTreePreorder(Context, ExpSplayTreeLargerChildNode(Node));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a splay tree using inorder traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpTraverseSplayTreeInorder(PTRAVERSE_CONTEXT Context,
|
||||||
|
PSPLAY_TREE_NODE Node)
|
||||||
|
{
|
||||||
|
PSPLAY_TREE_NODE n;
|
||||||
|
|
||||||
|
if (Node == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Traverse 'smaller' subtree */
|
||||||
|
ExpTraverseSplayTreeInorder(Context, ExpSplayTreeSmallerChildNode(Node));
|
||||||
|
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpSplayTreeNodeKey(Node),
|
||||||
|
ExpSplayTreeNodeValue(Node)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
|
||||||
|
{
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpSplayTreeNodeKey(n),
|
||||||
|
ExpSplayTreeNodeValue(n)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Traverse right subtree */
|
||||||
|
ExpTraverseSplayTreeInorder(Context, ExpSplayTreeLargerChildNode(Node));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a splay tree using postorder traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
* The lock for the tree must be acquired when this routine is called.
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
ExpTraverseSplayTreePostorder(PTRAVERSE_CONTEXT Context,
|
||||||
|
PSPLAY_TREE_NODE Node)
|
||||||
|
{
|
||||||
|
PSPLAY_TREE_NODE n;
|
||||||
|
|
||||||
|
if (Node == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Traverse 'smaller' subtree */
|
||||||
|
ExpTraverseSplayTreePostorder(Context, ExpSplayTreeSmallerChildNode(Node));
|
||||||
|
|
||||||
|
/* Traverse 'larger' subtree */
|
||||||
|
ExpTraverseSplayTreePostorder(Context, ExpSplayTreeLargerChildNode(Node));
|
||||||
|
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpSplayTreeNodeKey(Node),
|
||||||
|
ExpSplayTreeNodeValue(Node)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = ExpSplayTreeNodeSame(Node); n; n = ExpSplayTreeNodeSame(n))
|
||||||
|
{
|
||||||
|
/* Call the traversal routine */
|
||||||
|
if (!(*Context->Routine)(Context->Context,
|
||||||
|
ExpSplayTreeNodeKey(n),
|
||||||
|
ExpSplayTreeNodeValue(n)))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default key compare function. Compares the integer values of the two keys.
|
* Default key compare function. Compares the integer values of the two keys.
|
||||||
*/
|
*/
|
||||||
|
@ -1160,4 +1300,57 @@ ExWeightOfSplayTree(IN PSPLAY_TREE Tree,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse a splay tree using either preorder, inorder or postorder
|
||||||
|
* traversal method.
|
||||||
|
* Returns FALSE, if the traversal was terminated prematurely or
|
||||||
|
* TRUE if the callback routine did not request that the traversal
|
||||||
|
* be terminated prematurely.
|
||||||
|
*/
|
||||||
|
BOOLEAN STDCALL
|
||||||
|
ExTraverseSplayTree(IN PSPLAY_TREE Tree,
|
||||||
|
IN TRAVERSE_METHOD Method,
|
||||||
|
IN PTRAVERSE_ROUTINE Routine,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
TRAVERSE_CONTEXT tc;
|
||||||
|
BOOLEAN Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
tc.Routine = Routine;
|
||||||
|
tc.Context = Context;
|
||||||
|
|
||||||
|
ExpLockSplayTree(Tree, &OldIrql);
|
||||||
|
|
||||||
|
if (ExpSplayTreeRootNode(Tree) == NULL)
|
||||||
|
{
|
||||||
|
ExpUnlockSplayTree(Tree, &OldIrql);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Method)
|
||||||
|
{
|
||||||
|
case TraverseMethodPreorder:
|
||||||
|
Status = ExpTraverseSplayTreePreorder(&tc, ExpSplayTreeRootNode(Tree));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TraverseMethodInorder:
|
||||||
|
Status = ExpTraverseSplayTreeInorder(&tc, ExpSplayTreeRootNode(Tree));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TraverseMethodPostorder:
|
||||||
|
Status = ExpTraverseSplayTreePostorder(&tc, ExpSplayTreeRootNode(Tree));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpUnlockSplayTree(Tree, &OldIrql);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; $Id: ntoskrnl.def,v 1.131 2002/03/23 13:53:22 chorns Exp $
|
; $Id: ntoskrnl.def,v 1.132 2002/03/23 19:44:46 chorns Exp $
|
||||||
;
|
;
|
||||||
; reactos/ntoskrnl/ntoskrnl.def
|
; reactos/ntoskrnl/ntoskrnl.def
|
||||||
;
|
;
|
||||||
|
@ -98,12 +98,14 @@ ExDeleteBinaryTree@4
|
||||||
ExInsertBinaryTree@12
|
ExInsertBinaryTree@12
|
||||||
ExSearchBinaryTree@12
|
ExSearchBinaryTree@12
|
||||||
ExRemoveBinaryTree@12
|
ExRemoveBinaryTree@12
|
||||||
|
ExTraverseBinaryTree@16
|
||||||
ExInitializeSplayTree@16
|
ExInitializeSplayTree@16
|
||||||
ExDeleteSplayTree@4
|
ExDeleteSplayTree@4
|
||||||
ExInsertSplayTree@12
|
ExInsertSplayTree@12
|
||||||
ExSearchSplayTree@12
|
ExSearchSplayTree@12
|
||||||
ExRemoveSplayTree@12
|
ExRemoveSplayTree@12
|
||||||
ExWeightOfSplayTree@8
|
ExWeightOfSplayTree@8
|
||||||
|
ExTraverseSplayTree@16
|
||||||
ExInitializeHashTable@16
|
ExInitializeHashTable@16
|
||||||
ExDeleteHashTable@4
|
ExDeleteHashTable@4
|
||||||
ExInsertHashTable@16
|
ExInsertHashTable@16
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; $Id: ntoskrnl.edf,v 1.117 2002/03/23 13:53:22 chorns Exp $
|
; $Id: ntoskrnl.edf,v 1.118 2002/03/23 19:44:46 chorns Exp $
|
||||||
;
|
;
|
||||||
; reactos/ntoskrnl/ntoskrnl.def
|
; reactos/ntoskrnl/ntoskrnl.def
|
||||||
;
|
;
|
||||||
|
@ -98,12 +98,14 @@ ExDeleteBinaryTree=ExDeleteBinaryTree@4
|
||||||
ExInsertBinaryTree=ExInsertBinaryTree@12
|
ExInsertBinaryTree=ExInsertBinaryTree@12
|
||||||
ExSearchBinaryTree=ExSearchBinaryTree@12
|
ExSearchBinaryTree=ExSearchBinaryTree@12
|
||||||
ExRemoveBinaryTree=ExRemoveBinaryTree@12
|
ExRemoveBinaryTree=ExRemoveBinaryTree@12
|
||||||
|
ExTraverseBinaryTree=ExTraverseBinaryTree@16
|
||||||
ExInitializeSplayTree=ExInitializeSplayTree@16
|
ExInitializeSplayTree=ExInitializeSplayTree@16
|
||||||
ExDeleteSplayTree=ExDeleteSplayTree@4
|
ExDeleteSplayTree=ExDeleteSplayTree@4
|
||||||
ExInsertSplayTree=ExInsertSplayTree@12
|
ExInsertSplayTree=ExInsertSplayTree@12
|
||||||
ExSearchSplayTree=ExSearchSplayTree@12
|
ExSearchSplayTree=ExSearchSplayTree@12
|
||||||
ExRemoveSplayTree=ExRemoveSplayTree@12
|
ExRemoveSplayTree=ExRemoveSplayTree@12
|
||||||
ExWeightOfSplayTree=ExWeightOfSplayTree@8
|
ExWeightOfSplayTree=ExWeightOfSplayTree@8
|
||||||
|
ExTraverseSplayTree=ExTraverseSplayTree@16
|
||||||
ExInitializeHashTable=ExInitializeHashTable@16
|
ExInitializeHashTable=ExInitializeHashTable@16
|
||||||
ExDeleteHashTable=ExDeleteHashTable@4
|
ExDeleteHashTable=ExDeleteHashTable@4
|
||||||
ExInsertHashTable=ExInsertHashTable@16
|
ExInsertHashTable=ExInsertHashTable@16
|
||||||
|
|
Loading…
Reference in a new issue