在bsearch()中自定义比较

时间:2010-03-24 05:24:30

标签: c++ bsearch

我有一个指向整数的地址数组(这些整数 按升序排序)。它们具有重复值。例如:1, 2,2,3,3,3,4,4 ......

我试图抓住所有大于a的值 一定的价值(关键)。目前正在尝试使用二进制实现它 搜索算法 -

void *bsearch(
 const void *key,
 const void *base,
 size_t num,
 size_t width,
 int ( __cdecl *compare ) ( const void *, const void *)
);

我无法完全实现这一点,但对于其中一些人来说。

是否有任何其他方法来掌握所有的价值观 数组,没有更改我正在使用的算法?

4 个答案:

答案 0 :(得分:2)

正如Klatchko和GMan所指出的那样,STL功能可以准确地为您提供所需信息:std::upper_bound

但是,如果您需要坚持使用bsearch,最简单的解决方案可能是向前迭代,直到达到新值。

void* p = bsearch(key, base, num, width, compare);
while ((p != end) &&           // however you define the end of the array - 
                               // base + num, perhaps?
       (compare(key, p)==0)){  // while p points to an element matching the key

   ++p; // advance p
}

如果您想获得匹配键的第一个p,而不是第一个更大的p,请使用--p代替++p

无论你喜欢这个还是重复的二进制搜索,正如迈克尔建议的那样,取决于数组的大小和你期望的重复次数。

现在,你的问题标题是指自定义比较函数,但是我理解这里无法帮助你的问题 - 比较函数必须将任意两个等效对象比较为等价,所以它不适合识别哪个几个等效对象是数组中其类型的第一个/最后一个。除非你有一个不同的问题,特别是关于比较功能?

答案 1 :(得分:1)

您应该查看std::upper_bound

例如,要查找第一个值的地址> 3:

const int data[] = { 1, 2, 2, 3, 3, 3, 3, 4, 4, ... };
size_t data_count = sizeof(data) / sizeof(*data);

const int *ptr = std::upper_bound(data, data + data_count, 3);

// ptr will now point to the address of the first 4

相关功能是std::lower_bound

答案 2 :(得分:1)

是的,您可以使用二进制搜索。诀窍就是你找到一个带有给定键的元素时所做的...除非你的下部和上部索引是相同的,你需要在你的间隔的左边部分继续二进制搜索...也就是说,你应该移动上限为当前中点。这样,当您的二进制搜索终止时,您将找到第一个这样的元素。然后迭代其余部分。

答案 3 :(得分:0)

如果您实施了二叉搜索树,则可以使用tree traversal算法执行此操作。您可以到达所需的“上限”节点,并从那里按顺序遍历。遍历比多次搜索树更简单,即遍历n个节点的树最多将执行 n 操作,而搜索n次将采用(n.log n)运营。