binarysearch.c
来自「Sun公司Dream项目」· C语言 代码 · 共 143 行
C
143 行
/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.php
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* http://www.opensource.org/licenses/cddl1.php. If
* applicable, add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced
* with your own identifying information:
* Portions Copyright [yyyy]
* [name of copyright owner]
*/
/*
* $(@)BinarySearch.c $Revision: 1.2 $ $Date: 2006/07/15 00:02:33 $
*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
*/
/*
* Copyright (c) 1995 by Sun Microsystems, Inc.
*/
#pragma ident "@(#)BinarySearch.c 1.1 98/10/22 SMI"
/*
* BinarySearch.c -- A generalized binary search algorithm.
*/
#include "cobjs/Log.h"
#include "cobjs/Macros.h"
#include "cobjs/Types.h"
#include "cobjs/BinarySearch.h"
#define PTR(base, width, i) ((void *)(((char *)base) + ((width) * (i))))
BinarySearchResult
binarySearch(const void *base, size_t nel, size_t width, const void *targetp,
int (*compar) (const void *el1p, const void *el2p),
BinarySearchOption opt, int *indexp)
{
int low = 0;
int high = nel - 1;
int probe;
int cmp;
Boolean isReverse;
BinarySearchResult result;
/*
* isReverse is TRUE if data is ordered with decreasing values as index
* increases
*/
if (nel == 0) {
probe = 0;
switch (opt) {
case BINARY_SEARCH_LOWER:
case BINARY_SEARCH_FLOOR:
result = BINARY_SEARCH_BEFORE;
break;
case BINARY_SEARCH_HIGHER:
case BINARY_SEARCH_CEIL:
result = BINARY_SEARCH_AFTER;
break;
default:
result = BINARY_SEARCH_AFTER;
ABORT("illegal binary search option");
break;
}
goto done;
}
isReverse = Boolean((*compar) (PTR(base, width, 0),
PTR(base, width, nel - 1)) > 0);
while (high - low > 1) {
int cmp;
probe = (low + high) / 2;
cmp = (*compar) (targetp, PTR(base, width, probe));
if (cmp == 0) {
result = BINARY_SEARCH_MATCH;
goto done;
}
if (isReverse ^ (cmp < 0)) {
high = probe;
} else {
low = probe;
}
}
/*
* At this point, high - low <= 1 (0 is only possible if nel == 1).
* Target can be anywhere in relationship to high and low (because it
* could be outside the range of all values in the table).
*/
cmp = (*compar) (targetp, PTR(base, width, high));
if (cmp == 0 || (isReverse ^ (cmp > 0))) {
probe = high;
result = (cmp == 0) ? BINARY_SEARCH_MATCH : BINARY_SEARCH_AFTER;
ASSERT(cmp == 0 || high == nel - 1);
goto done;
}
cmp = (*compar) (targetp, PTR(base, width, low));
if (cmp == 0 || (isReverse ^ (cmp < 0))) {
probe = low;
result = (cmp == 0) ? BINARY_SEARCH_MATCH : BINARY_SEARCH_BEFORE;
ASSERT(cmp == 0 || low == 0);
goto done;
}
/*
* Target is between low and high
*/
result = BINARY_SEARCH_BETWEEN;
switch (opt) {
case BINARY_SEARCH_LOWER:
probe = low;
break;
case BINARY_SEARCH_HIGHER:
probe = high;
break;
case BINARY_SEARCH_FLOOR:
probe = isReverse ? high : low;
break;
case BINARY_SEARCH_CEIL:
probe = isReverse ? low : high;
break;
default:
probe = 0;
ABORT("illegal binary search option");
break;
}
done:
if (indexp != NULL) {
*indexp = probe;
}
return result;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?