【问题标题】:Is my binary search algorithm (a) correct and (b) efficient?我的二分搜索算法 (a) 是否正确且 (b) 有效?
【发布时间】:2013-10-27 21:14:18
【问题描述】:

我已经编写了一个简单的方法来将新元素添加到排序列表类中,代码在 Dart 中,但在所有类似 C 的语言中发生的事情应该相当明显,我已经运行了几个简单的单元测试它似乎确实以正确的顺序添加了新元素,我的问题是,它是否充分证明?它可以更有效吗?我正在尝试使用二进制搜索来查找要插入的适当索引,它还返回插入新对象的索引:

int add(T obj){

  int loIdx = 0;
  int upIdx = list.length - 1;
  int i;

  while(loIdx <= upIdx){

    i = loIdx + ((upIdx - loIdx) >> 1);

    switch(_compare(obj, list[i])){

      case 0:

        loIdx = i;

        upIdx = i - 1;

        break;

      case -1:

        upIdx = i - 1;

        if(loIdx == upIdx){

          if(_compare(obj, list[loIdx]) == 1){

            loIdx++;

          }

        }

        break;

      case 1:

        loIdx = i + 1;

        break;

    }

  }

  list.insert(loIdx, obj);

  return loIdx;

}

为了完整起见,这是我用来证明它确实有效的单元测试之一:

test('Order',(){

  SortedList<int> intList = new SortedList<int>((int a, int b) => a.compareTo(b));

  intList.add(5);
  intList.add(7);
  intList.add(0);
  intList.add(3);
  intList.add(6);
  intList.add(9);
  intList.add(1);
  intList.add(2);
  intList.add(8);
  intList.add(5);
  intList.add(4);

  expect(intList.list, orderedEquals([0,1,2,3,4,5,5,6,7,8,9]));

});

【问题讨论】:

    标签: algorithm search dart binary-search


    【解决方案1】:

    我从来没有用过 Dart,但是这行:

    i = loIdx + ((upIdx - loIdx) % 2);
    

    看起来很奇怪。通常我希望看到类似的东西:

    i = loIdx + ((upIdx - loIdx) >> 1);
    

    i = loIdx + ((upIdx - loIdx) / 2);
    

    【讨论】:

    • @MarioP:我认为彼得是对的:您搜索的是中间索引,因此您应该使用整数除以二 (~/2),或者更快地使用移位 (>>1)。到目前为止,您的算法每次只移动一个(甚至 0)索引,所以它是 O(n^2),而不是 O(ln(n))。此外,请注意开销:对于小列表(例如
    • @GameAlchemist 抱歉,我并没有真正看代码本身 - 措辞让我觉得它在语法上很奇怪。我可能应该更仔细地阅读。
    • 我虽然 x % 2 是 x >> 1,哎呀!这很糟糕,我不敢相信它在这种情况下甚至都有效。谢谢我忘了模返回余数而不是整数除法的值。
    猜你喜欢
    • 2019-10-31
    • 1970-01-01
    • 2019-08-29
    • 2022-01-11
    • 2021-03-23
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    相关资源
    最近更新 更多