Search in circular Array

烂漫一生 提交于 2019-12-20 04:18:27

问题


What is the best way to search in a circular array?

Example 1  array : 45 67 44 11 49 4 56 12 39 90
           circular array 11, 49, 4, 56, 12, 39, 90, 45, 67

Is Binary search the right approach to start with?


回答1:


Binary search is only useful if the array is sorted.

You didn't provide much info about the problem domain but one approach would be to use a set (or hash table). For every number you put in the array, also insert it in the set. Lookups in a set (or hash table) happen in constant time, so there's no "searching". When you remove an item from the array, also remove it from the set. If your circular buffer overwrites values as it fills up, make sure it also updates the set to remove overwritten values.

If you can't use another data structure, then the best you can do is a linear scan of the array.




回答2:


Had this same problem, couldn't see a way to use builtin functions without running the search twice so wrote a custom one.

There is probably a way to do the out of range check quicker, but this serves my purpose. (Didn't want to copy the standard binary search interface with the negative index stuff as the consumer converting it back to real indexes on a circular buffer would have been painful)

public bool BinarySearchCircular<T>(T[] array, T searchValue, int head, out int lowerIndex, out int upperIndex) where T : IComparable<T>
{
  int bottom = 0;
  int top = (int)array.Length - 1;
  int count = (int)array.Length;
  int middle = top >> 1;
  while (top >= bottom)
  {
      int middleIndex = (middle + head) % count;
      if (array[middleIndex].CompareTo(searchValue) == 0)
      {
          upperIndex = middleIndex;
          lowerIndex = middleIndex;
          return true;
      }
      else if (array[middleIndex].CompareTo(searchValue) > 0)
      {
          top = middle - 1;
      }
      else
      { 
          bottom = middle + 1; 
      }
      middle = (bottom + top) >> 1;
  }
  if(array[head].CompareTo(searchValue) < 0)
  {
    lowerIndex = head;
    upperIndex = -1;
  }
  else if(array[(head+1) % count].CompareTo(searchValue)  > 0)
  {
    upperIndex = (head+1) % count;
    lowerIndex = -1;
  }
  else
  {
    lowerIndex = (top + head) % count;
    upperIndex = (bottom + head) % count;
  }

  return false;       
}


来源:https://stackoverflow.com/questions/7693992/search-in-circular-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!