mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[SKIPLIST]
- Add a LookupNodeByIndexSkiplist function and a small test for it in skiplist_test. - Remove a redundant double-set in LookupElementSkiplist. Yes, we now have one lookup function that accepts search criteria and returns an element and another one that accepts an index and returns a SKIPLIST_NODE. It's simply because I have exactly these two cases :) You're free to implement the two missing functions or refactor this code another way. svn path=/branches/colins-printing-for-freedom/; revision=68262
This commit is contained in:
parent
7aef841dea
commit
84416a465a
3 changed files with 51 additions and 2 deletions
|
@ -366,8 +366,6 @@ LookupElementSkiplist(PSKIPLIST Skiplist, PVOID Element, PDWORD ElementIndex)
|
|||
// * Walk through all nodes on this level that come before the node we're looking for.
|
||||
// * When we have reached such a node, go down a level and continue there.
|
||||
// * Repeat these steps till we're in level 0, right in front of the node we're looking for.
|
||||
pNode = &Skiplist->Head;
|
||||
|
||||
for (i = Skiplist->MaximumLevel + 1; --i >= 0;)
|
||||
{
|
||||
while (pNode->Next[i] && pNode->Next[i] != pLastComparedNode && Skiplist->CompareRoutine(pNode->Next[i]->Element, Element) < 0)
|
||||
|
@ -395,3 +393,48 @@ LookupElementSkiplist(PSKIPLIST Skiplist, PVOID Element, PDWORD ElementIndex)
|
|||
// Return the stored element of the found node.
|
||||
return pNode->Element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name LookupNodeByIndexSkiplist
|
||||
*
|
||||
* Looks up a node in the Skiplist at the given position. The efficiency of this operation is O(log N) on average.
|
||||
*
|
||||
* @param Skiplist
|
||||
* Pointer to the SKIPLIST structure to operate on.
|
||||
*
|
||||
* @param ElementIndex
|
||||
* Zero-based position of the node in the Skiplist.
|
||||
*
|
||||
* @return
|
||||
* Returns the found node or NULL if the position is invalid.
|
||||
*/
|
||||
PSKIPLIST_NODE
|
||||
LookupNodeByIndexSkiplist(PSKIPLIST Skiplist, DWORD ElementIndex)
|
||||
{
|
||||
CHAR i;
|
||||
DWORD dwIndex = 0;
|
||||
PSKIPLIST_NODE pNode = &Skiplist->Head;
|
||||
|
||||
// The only way the node can't be found is when the index is out of range.
|
||||
if (ElementIndex >= Skiplist->NodeCount)
|
||||
return NULL;
|
||||
|
||||
// Do the efficient lookup in Skiplists:
|
||||
// * Start from the maximum level.
|
||||
// * Walk through all nodes on this level that come before the node we're looking for.
|
||||
// * When we have reached such a node, go down a level and continue there.
|
||||
// * Repeat these steps till we're in level 0, right in front of the node we're looking for.
|
||||
for (i = Skiplist->MaximumLevel + 1; --i >= 0;)
|
||||
{
|
||||
// We compare with <= instead of < here, because the added distances make up a 1-based index while ElementIndex is zero-based,
|
||||
// so we have to jump one node further.
|
||||
while (pNode->Next[i] && dwIndex + pNode->Distance[i] <= ElementIndex)
|
||||
{
|
||||
dwIndex += pNode->Distance[i];
|
||||
pNode = pNode->Next[i];
|
||||
}
|
||||
}
|
||||
|
||||
// We are right in front of the node we're looking for now.
|
||||
return pNode->Next[0];
|
||||
}
|
||||
|
|
|
@ -49,5 +49,6 @@ BOOL InsertElementSkiplist(PSKIPLIST Skiplist, PVOID Element);
|
|||
BOOL InsertTailElementSkiplist(PSKIPLIST Skiplist, PVOID Element);
|
||||
PVOID DeleteElementSkiplist(PSKIPLIST Skiplist, PVOID Element);
|
||||
PVOID LookupElementSkiplist(PSKIPLIST Skiplist, PVOID Element, PDWORD ElementIndex);
|
||||
PSKIPLIST_NODE LookupNodeByIndexSkiplist(PSKIPLIST Skiplist, DWORD ElementIndex);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,6 +67,7 @@ main()
|
|||
DWORD ElementIndex;
|
||||
DWORD i;
|
||||
SKIPLIST Skiplist;
|
||||
PSKIPLIST_NODE pNode;
|
||||
|
||||
system("mode con cols=300");
|
||||
InitializeSkiplist(&Skiplist, MyAlloc, MyCompare, MyFree);
|
||||
|
@ -83,6 +84,10 @@ main()
|
|||
for (i = 0; i < 40; i++)
|
||||
InsertElementSkiplist(&Skiplist, (PVOID)(rand() % 100));
|
||||
|
||||
// Output the third element (with zero-based index 2).
|
||||
pNode = LookupNodeByIndexSkiplist(&Skiplist, 2);
|
||||
printf("Element = %lu for index 2\n", (DWORD)pNode->Element);
|
||||
|
||||
// Check if an element with number 44 is in the list and output its index.
|
||||
Element = (DWORD)LookupElementSkiplist(&Skiplist, (PVOID)44, &ElementIndex);
|
||||
printf("Element = %lu, ElementIndex = %lu\n\n", Element, ElementIndex);
|
||||
|
|
Loading…
Reference in a new issue