二进制搜索以确定放置值的位置

时间:2013-12-09 22:13:43

标签: c++ arrays hash binary-search-tree

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

我遇到了这个功能的问题。它应该有这样的原型:

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

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

3 个答案:

答案 0 :(得分:0)

通常,哈希用作数组的索引。此外,当使用哈希时,您可能会得到一个按哈希排序但不是键的数组(尽管如此,它显而易见)。如果你真的想要找到一个键应该放在一个排序数组中的位置,你可以使用std::lower_bound()

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

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

答案 1 :(得分:0)

您正在实施不同实施类型的

地图包含一个键和值对 - 您只有一个键 - 所以它是设置

哈希意味着另一件事 - 它们是无序的并且使用哈希函数为具有相同哈希的所有项目的列表选择一个桶,称为冲突(一些变体使用其他方案来处理碰撞)。这在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;
}

答案 2 :(得分:0)

认真阅读: binary search wiki

尝试这样的事情:

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;
}