二叉搜索以确定放置值的位置

Binary search to determine where to place value

本文关键字:位置 搜索      更新时间:2023-10-16

我正在编写 c++ 代码来使用各种技术(数组、二叉树等(实现哈希映射。我卡在按数组实现时。我需要一种方法来确定放置新哈希的位置,以便在放置数组后对数组进行排序。我的想法是使用二叉搜索来确定放置新哈希的索引,然后推送所有其他元素。

我的功能有问题。它应该有一些这样的原型:

int WhereToPlaceHash(HashType hash); // uses private atribute ValueType** values

我已经尽力编写这个函数,但我所有的尝试都导致了无限循环并从数组中读取无效位置。请帮忙。

通常,哈希用作数组的索引。此外,使用哈希时,您可能会得到一个按哈希排序但不按键排序的数组(不过这很明显(。如果你真的想找到键应该在排序数组中的位置,你可以使用std::lower_bound()

int* pos = std::lower_bound(array, array + array_size, key);

返回迭代器pos将指向第一个位置,以便!(key < *pos) .

您正在实现一组不同的实现类型

映射包含一个键和值对 - 你只有一个键 - 所以它是一个集合

哈希意味着不同的东西 - 它们是无序的,并使用哈希函数为具有相同哈希的所有项目的列表选择一个存储桶,称为碰撞(某些变体使用其他方案来处理冲突(。 这在STL中被暗示为std::unordered_setstd::unsordered_map,...

对于已排序的数组实现,请使用保存在排序数组中的数组,然后执行必须将所有项目移得更大的插入操作以保持排序顺序。 然后,您的查找将执行二叉搜索

插入将使用二叉搜索来查找放置项目的位置,然后将所有大于它的项目移动。

二叉搜索从中间开始,然后重复检查(低+中(/2(如果更低或(中+最高(/2(如果更大(,直到找到位置

请注意,您必须区分已找到和未找到

int binsearch(int * array, int len, int value, bool * found)
{
    // return lowest position greater or equal to value
    int lowp=0;
    int highp=len-1;
    int midp=(lowp+highp)/2;
    while (lowp <=highp)
    {
        int mid=array[midp];
        if (mid > value)
        {
            highp=midp-1;
        }
        else if (value==mid)
        {
            *found=true;
            return midp; // found at this position
        }
        else
        {
            lowp=midp+1;
        }
        midp=(lowp+highp)/2;
    }
    *found=false;
    if (array[midp] > value)
    {
        return midp;  // only at position 0 for a head insert
    }
    return midp+1; // not found - position to start shift
}
int main(int, char**)
{
    int array[]={2,4,6,8,10,12,14,16,18,20};
    bool found;
    for (int search=1; search < 22; ++search)
    {
        int a=binsearch(array, 10, search, &found);
        std::cout << search << " at " << a << ":" << found << std::endl;
    }
    return 0;
}

仔细阅读:二叉搜索维基

并尝试这样的事情:

int WhereToPlaceHash(int hash) {
    int imin = 0, imax = YourSizeOfArray;
    int imid = 0;
  while (imax >= imin) {
      imid = (imax + imin) / 2;
      if(YourArray[imid] == hash)
        return imid + 1; 
      else if (YourArray[imid] < hash)
        break;
      else         
        imax = imid - 1;
    }
  return imid;
}