|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/corelib/binary.c |
source navigation diff markup identifier search freetext search file search |
1 /* $Id: binary.c,v 1.6 2000/08/28 18:47:40 vakatov Exp $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: $Id: binary.c,v 1.6 2000/08/28 18:47:40 vakatov Exp $
27 *
28 * Author: Lewis Geer
29 *
30 * Version Creation Date: 8/24/99
31 *
32 * $Revision: 1.6 $
33 *
34 * File Description: Various binary search algorithms
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * $Log: binary.c,v $
39 * Revision 1.6 2000/08/28 18:47:40 vakatov
40 * Added missing type cast to pass C++ compilation
41 *
42 * Revision 1.5 1999/11/23 22:02:29 vakatov
43 * Fixed for the MSVC DLL compilation
44 *
45 * Revision 1.4 1999/10/14 22:00:33 vakatov
46 * More changes in the included headers
47 *
48 * Revision 1.3 1999/10/14 19:08:09 kans
49 * header changes for Mac
50 *
51 * Revision 1.2 1999/10/05 23:18:25 lewisg
52 * add ddv and udv to cn3d with memory management
53 *
54 * Revision 1.1 1999/09/21 18:09:13 lewisg
55 * binary search added to color manager, various bug fixes, etc.
56 * ==========================================================================
57 */
58
59 #include <binary.h>
60
61
62 /*****************************************************************************
63 *
64 * B_NewGlobal() returns a new binary search global. Takes a key comparison
65 * function and the size to realloc the binary search list. If you pass 0
66 * for AllocSize it will use the default value B_ALLOCSIZE * sizeof(B_List).
67 * Returns NULL on failure.
68 *
69 * B_DeleteGlobal() deletes the global. Return 1 on success, 0 on failure.
70 *
71 *****************************************************************************/
72
73 NLM_EXTERN B_Global * B_NewGlobal(B_CompareFunc CompareFunc, Int4 AllocSize)
74 {
75 B_Global * pGlobal;
76
77 if (CompareFunc == NULL) return NULL;
78 pGlobal = (B_Global *) MemNew(sizeof(B_Global));
79 if(pGlobal == NULL) return NULL;
80
81 /* pGlobal->RW = NlmRWinit(); */
82 if(AllocSize == 0) pGlobal->AllocSize = B_ALLOCSIZE;
83 else pGlobal->AllocSize = AllocSize;
84 pGlobal->CompareFunc = CompareFunc;
85 pGlobal->List = NULL;
86 pGlobal->Size = 0;
87 pGlobal->TrueSize = 0;
88 pGlobal->Cursor = -1;
89
90 return pGlobal;
91 }
92
93 NLM_EXTERN Int4 B_DeleteGlobal(B_Global *pGlobal)
94 {
95 if(pGlobal == NULL) return 0;
96
97 MemFree(pGlobal->List);
98 /* NlmRWdestroy(pGlobal->RW); */
99 MemFree(pGlobal);
100
101 return 1;
102 }
103
104
105 /*****************************************************************************
106 *
107 * Inserts a new entry into the List. Returns the position. The position
108 * is not guaranteed between deletions and insertions
109 *
110 * Automatically reallocates memory for List as List grows
111 *
112 *****************************************************************************/
113
114 NLM_EXTERN Int4 B_Insert(B_Global *pGlobal, void *Key, void *Bag)
115 {
116 Int4 InsertPos;
117 Boolean NotFound, InsertBefore = TRUE;
118
119 if(pGlobal == NULL || Key == NULL) return 0;
120
121 if(pGlobal->Size !=0) {
122 InsertPos = B_GetFirst(pGlobal, Key, &NotFound);
123 if(InsertPos == INT4_MIN) return 0;
124 /* scan for insertion point */
125 if(InsertPos == B_GetSize(pGlobal)) InsertBefore = FALSE;
126 else if((*pGlobal->CompareFunc)(Key, pGlobal->List[InsertPos].Key) > 0)
127 InsertBefore = FALSE;
128 }
129 else InsertPos = 0;
130
131 /* make the List bigger if necessary */
132 if(pGlobal->TrueSize == 0) {
133 pGlobal->TrueSize += pGlobal->AllocSize;
134 pGlobal->List = (B_List *)Nlm_MemNew((size_t)pGlobal->TrueSize * sizeof(B_List));
135 if(pGlobal->List == NULL) return -1;
136 }
137 else if (pGlobal->Size == pGlobal->TrueSize) {
138 pGlobal->TrueSize += pGlobal->AllocSize;
139 pGlobal->List = (B_List *)Nlm_MemMore((void *)pGlobal->List,
140 (size_t) pGlobal->TrueSize * sizeof(B_List));
141 if(pGlobal->List == NULL) return -1;
142 }
143
144 if(InsertBefore) {
145 Nlm_MemMove(&pGlobal->List[InsertPos + 1], &pGlobal->List[InsertPos],
146 (size_t)(pGlobal->Size - InsertPos) * sizeof(B_List));
147
148 pGlobal->List[InsertPos].Key = Key;
149 pGlobal->List[InsertPos].Bag = Bag;
150 }
151 else if(InsertPos == B_GetSize(pGlobal)) {
152 pGlobal->List[InsertPos].Key = Key;
153 pGlobal->List[InsertPos].Bag = Bag;
154 }
155 else {
156 Nlm_MemMove(&pGlobal->List[InsertPos + 1], &pGlobal->List[InsertPos],
157 (size_t)(pGlobal->Size - InsertPos) * sizeof(B_List));
158
159 pGlobal->List[InsertPos + 1].Key = Key;
160 pGlobal->List[InsertPos + 1].Bag = Bag;
161 }
162
163 pGlobal->Size++;
164
165 return InsertPos;
166 }
167
168 /*****************************************************************************
169 *
170 * B_Get() Returns the position in the List associated with the key.
171 * Returns INT4_MIN if no match or the list is empty.
172 *
173 * B_GetFirst() does the same, but returns the first item in the List that
174 * matches the Key.
175 *
176 * B_GetBag() gets bag associated with the key.
177 *
178 *****************************************************************************/
179
180
181 NLM_EXTERN Int4 B_Get(B_Global *pGlobal, void *Key, Boolean *NotFound)
182 {
183 Int4 x, l, r;
184 Int4 CompareValue;
185
186 if(pGlobal == NULL || Key == NULL) {
187 *NotFound = TRUE;
188 return INT4_MIN;
189 }
190
191 *NotFound = FALSE;
192
193 if(pGlobal->Cursor >= 0)
194 if ((*pGlobal->CompareFunc)(Key, pGlobal->List[pGlobal->Cursor].Key) == 0)
195 return pGlobal->Cursor;
196
197 if(pGlobal->Size == 0) {
198 *NotFound = TRUE;
199 return 0;
200 }
201
202 l = 0;
203 r = B_GetSize(pGlobal) - 1;
204
205 while (TRUE) {
206 x = (l + r)/2;
207 CompareValue = (*pGlobal->CompareFunc)(Key, pGlobal->List[x].Key);
208 if (CompareValue == 0) {
209 pGlobal->Cursor = x;
210 return x;
211 }
212 if (r <= l) break;
213 if (CompareValue < 0) {
214 if (x > 0) r = x - 1;
215 else r = 0;
216 }
217 else {
218 if (x < B_GetSize(pGlobal) - 1) l = x + 1;
219 else l = B_GetSize(pGlobal) - 1;
220 }
221 }
222 *NotFound = TRUE; /* not found */
223 return x;
224 }
225
226
227 NLM_EXTERN Int4 B_GetFirst(B_Global *pGlobal, void *Key, Boolean *NotFound)
228 {
229 Int4 i, j;
230
231 i = B_Get(pGlobal, Key, NotFound);
232 if(B_GetSize(pGlobal) < 2) return i;
233
234 if(*NotFound) {
235 if( i == INT4_MIN) return i;
236 for(j = -1; j < 2; j++) {
237 if(j + i < 0 ) continue;
238 if(j + i >= B_GetSize(pGlobal)) break;
239 if((*pGlobal->CompareFunc)(Key, pGlobal->List[j+i].Key) < 0) break;
240 }
241 return j + i;
242 }
243
244 if(i == 0) return i;
245 while((*pGlobal->CompareFunc)(pGlobal->List[i].Key, pGlobal->List[i-1].Key)
246 == 0 && i > 1) i--;
247
248 return i;
249 }
250
251 NLM_EXTERN void * B_GetBag(B_Global *pGlobal, void *Key)
252 {
253 Int4 i;
254 Boolean NotFound;
255
256 i = B_Get(pGlobal, Key, &NotFound);
257 if(NotFound) return NULL;
258 else return pGlobal->List[i].Bag;
259 }
260
261
262 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |