source: trunk/include/k/kAvlTmpl/kAvlRemove2.h@ 4

Last change on this file since 4 was 2, checked in by bird, 18 years ago

Imported http://svn.netlabs.org/repos/libc/trunk/kStuff, revision 3612.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 4.0 KB
Line 
1/* $Id: kAvlRemove2.h 2 2007-11-16 16:07:14Z bird $ */
2/** @file
3 * kAvlTmpl - Templated AVL Trees, Remove A Specific Node.
4 */
5
6/*
7 * Copyright (c) 1999-2007 knut st. osmundsen <bird-src-spam@anduin.net>
8 *
9 * This file is part of kStuff.
10 *
11 * kStuff is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * kStuff is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with kStuff; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 *
26 * As a special exception, since this is a source file and not a header
27 * file, you are granted permission to #include this file as you wish
28 * without this in itself causing the resulting program or whatever to be
29 * covered by the LGPL license. This exception does not however invalidate
30 * any other reasons why the resulting program/whatever should not be
31 * covered the LGPL or GPL.
32 */
33
34
35/**
36 * Removes the specified node from the tree.
37 *
38 * @returns Pointer to the removed node (NULL if not in the tree)
39 * @param ppTree Pointer to Pointer to the tree root node.
40 * @param Key The Key of which is to be found a best fitting match for..
41 *
42 * @remark This implementation isn't the most efficient, but this short and
43 * easier to manage.
44 */
45KAVL_DECL(KAVLNODE *) KAVL_FN(Remove2)(KAVLTREEPTR *ppTree, KAVLNODE *pNode)
46{
47#ifdef KAVL_EQUAL_ALLOWED
48 /*
49 * Find the right node by key and see if it's what we want.
50 */
51 KAVLNODE *pParent;
52 KAVLNODE *pCurNode = KAVL_FN(GetWithParent)(ppTree, pNode->mKey, &pParent);
53 if (!pCurNode)
54 return NULL;
55 if (pCurNode != pNode)
56 {
57 /*
58 * It's not the one we want, but it could be in the duplicate list.
59 */
60 while (pCurNode->mpList != KAVL_NULL)
61 {
62 KAVLNODE *pNext = KAVL_GET_POINTER(&pCurNode->mpList);
63 if (pNext == pNode)
64 {
65 KAVL_SET_POINTER_NULL(&pCurNode->mpList, KAVL_GET_POINTER_NULL(&pNode->mpList));
66 pNode->mpList = KAVL_NULL;
67 return pNode;
68 }
69 pCurNode = pNext;
70 }
71 return NULL;
72 }
73
74 /*
75 * Ok, it's the one we want alright.
76 *
77 * Simply remove it if it's the only one with they Key,
78 * if there are duplicates we'll have to unlink it and
79 * insert the first duplicate in our place.
80 */
81 if (pNode->mpList == KAVL_NODE)
82 KAVL_FN(Remove)(ppTree, pNode->mKey);
83 else
84 {
85 KAVLNODE *pNewUs = KAVL_GET_POINTER(&pNode->mpList);
86
87 pNewUs->mHeight = pNode->mHeight;
88
89 if (pNode->mpLeft != KAVL_NULL)
90 KAVL_SET_POINTER(&pNewUs->mpLeft, KAVL_GET_POINTER(&pNode->mpLeft))
91 else
92 pNewUs->mpLeft = KAVL_NULL;
93
94 if (pNode->mpRight != KAVL_NULL)
95 KAVL_SET_POINTER(&pNewUs->mpRight, KAVL_GET_POINTER(&pNode->mpRight))
96 else
97 pNewUs->mpRight = KAVL_NULL;
98
99 if (pParent)
100 {
101 if (KAVL_GET_POINTER_NULL(&pParent->mpLeft) == pNode)
102 KAVL_SET_POINTER(&pParent->mpLeft, pNewUs);
103 else
104 KAVL_SET_POINTER(&pParent->mpRight, pNewUs);
105 }
106 else
107 KAVL_SET_POINTER(ppTree, pNewUs);
108 }
109 return pNode;
110
111#else
112 /*
113 * Delete it, if we got the wrong one, reinsert it.
114 *
115 * This ASSUMS that the caller is NOT going to hand us a lot
116 * of wrong nodes but just uses this API for his convenience.
117 */
118 KAVLNODE *pRemovedNode = KAVL_FN(Remove)(ppTree, pNode->mKey);
119 if (pRemovedNode == pNode)
120 return pRemovedNode;
121
122 KAVL_FN(Insert)(ppTree, pRemovedNode);
123 return NULL;
124#endif
125}
126
Note: See TracBrowser for help on using the repository browser.