VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/table/avl_RemoveNode.cpp.h@ 65208

Last change on this file since 65208 was 65208, checked in by vboxsync, 8 years ago

Runtime/AVL: fixed headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.6 KB
Line 
1/* $Id: avl_RemoveNode.cpp.h 65208 2017-01-09 14:39:54Z vboxsync $ */
2/** @file
3 * kAVLRemove2 - Remove specific node (by pointer) from an AVL tree.
4 */
5
6/*
7 * Copyright (C) 2001-2012 knut st. osmundsen (bird-src-spam@anduin.net)
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32/**
33 * Removes the specified node from the tree.
34 *
35 * @returns Pointer to the removed node (NULL if not in the tree)
36 * @param ppTree Pointer to the AVL-tree root structure.
37 * @param pNode Pointer to the node to be removed.
38 *
39 * @remark This implementation isn't the most efficient, but it's relatively
40 * short and easier to manage.
41 */
42KAVL_DECL(PKAVLNODECORE) KAVL_FN(RemoveNode)(PPKAVLNODECORE ppTree, PKAVLNODECORE pNode)
43{
44#ifdef KAVL_EQUAL_ALLOWED
45 /*
46 * Find the right node by key together with the parent node.
47 */
48 KAVLKEY const Key = pNode->Key;
49 PKAVLNODECORE pParent = NULL;
50 PKAVLNODECORE pCurNode = KAVL_GET_POINTER_NULL(ppTree);
51 if (!pCurNode)
52 return NULL;
53 while (KAVL_NE(pCurNode->Key, Key))
54 {
55 pParent = pCurNode;
56 if (KAVL_G(pCurNode->Key, Key))
57 {
58 if (pCurNode->pLeft != KAVL_NULL)
59 pCurNode = KAVL_GET_POINTER(&pCurNode->pLeft);
60 else
61 return NULL;
62 }
63 else
64 {
65 if (pCurNode->pRight != KAVL_NULL)
66 pCurNode = KAVL_GET_POINTER(&pCurNode->pRight);
67 else
68 return NULL;
69 }
70 }
71
72 if (pCurNode != pNode)
73 {
74 /*
75 * It's not the one we want, but it could be in the duplicate list.
76 */
77 while (pCurNode->pList != KAVL_NULL)
78 {
79 PKAVLNODECORE pNext = KAVL_GET_POINTER(&pCurNode->pList);
80 if (pNext == pNode)
81 {
82 if (pNode->pList != KAVL_NULL)
83 KAVL_SET_POINTER(&pCurNode->pList, KAVL_GET_POINTER(&pNode->pList));
84 else
85 pCurNode->pList = KAVL_NULL;
86 pNode->pList = KAVL_NULL;
87 return pNode;
88 }
89 pCurNode = pNext;
90 }
91 return NULL;
92 }
93
94 /*
95 * Ok, it's the one we want alright.
96 *
97 * Simply remove it if it's the only one with they Key, if there are
98 * duplicates we'll have to unlink it and insert the first duplicate
99 * in our place.
100 */
101 if (pNode->pList == KAVL_NULL)
102 KAVL_FN(Remove)(ppTree, pNode->Key);
103 else
104 {
105 PKAVLNODECORE pNewUs = KAVL_GET_POINTER(&pNode->pList);
106
107 pNewUs->uchHeight = pNode->uchHeight;
108
109 if (pNode->pLeft != KAVL_NULL)
110 KAVL_SET_POINTER(&pNewUs->pLeft, KAVL_GET_POINTER(&pNode->pLeft));
111 else
112 pNewUs->pLeft = KAVL_NULL;
113
114 if (pNode->pRight != KAVL_NULL)
115 KAVL_SET_POINTER(&pNewUs->pRight, KAVL_GET_POINTER(&pNode->pRight));
116 else
117 pNewUs->pRight = KAVL_NULL;
118
119 if (pParent)
120 {
121 if (KAVL_GET_POINTER_NULL(&pParent->pLeft) == pNode)
122 KAVL_SET_POINTER(&pParent->pLeft, pNewUs);
123 else
124 KAVL_SET_POINTER(&pParent->pRight, pNewUs);
125 }
126 else
127 KAVL_SET_POINTER(ppTree, pNewUs);
128 }
129
130 return pNode;
131
132#else
133 /*
134 * Delete it, if we got the wrong one, reinsert it.
135 *
136 * This ASSUMS that the caller is NOT going to hand us a lot
137 * of wrong nodes but just uses this API for his convenience.
138 */
139 KAVLNODE *pRemovedNode = KAVL_FN(Remove)(pRoot, pNode->Key);
140 if (pRemovedNode == pNode)
141 return pRemovedNode;
142
143 KAVL_FN(Insert)(pRoot, pRemovedNode);
144 return NULL;
145#endif
146}
147
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette