簡體   English   中英

BinarySearch即使在列表中也找不到元素:Java

[英]BinarySearch does not find element in list even when it's there : Java

誰能指出我在哪里出問題了? 我使用調試器逐步完成了它,看起來我的算法應該找到了搜索關鍵字,但並非如此。 (為進行檢查,我先打印出“在索引處找到”,然后打印[已排序]列表的內容;我搜索的元素123在列表中,但返回的“未找到”值為-1。)

public int binarySearch(ArrayList<Integer> list, int key){
    int foundAtIndex  = -1;
    int midPoint = list.size()/2;
    int midPointValue = list.get(midPoint);

    if(list.size() > 1){
        if(midPointValue == key){
            foundAtIndex = midPoint;
        }
        else if(midPointValue > key){
            ArrayList<Integer> newList = new ArrayList<Integer>();
            for(int i = 0; i < midPoint; i++){
                newList.add(list.get(i));
            }
            midPoint = midPoint / 2;
            binarySearch(newList, key);
        }
        else if(midPointValue < key){
            ArrayList<Integer> newList = new ArrayList<Integer>();
            for(int j = midPoint+1; j < list.size(); j++){
                newList.add(list.get(j));
            }
            midPoint = midPoint / 2;
            binarySearch(newList, key);
        }
    }
    else if(list.size() == 1){
        if(list.get(0) == key){
            foundAtIndex = 0;
        }
    }

    //return the index where the key was found, or -1 if not found
    return foundAtIndex;
}

編輯:好的,所以現在可以找到它,但是我的問題是我需要返回在原始數組中找到的索引。 照原樣,將其縮小,然后返回“ newList”中元素的索引。 因此,它將始終根據在“ newList”的索引處返回的值返回它。 換句話說,我正在尋找返回一個實際的foundAtIndex(該值在原始數組中的位置),而不是布爾值“是否已找到”。

每次您調用binarySearch(newList, key); 您正在失去返回結果。

您需要設置foundIndex = binarySearch(newList,key)

另外,由於您依賴list.size()作為中點-您將需要調整返回結果(否則它將始終為-1或0)。

您不存儲遞歸調用的返回值。 替換兩行

binarySearch(newList, key);

通過

foundAtIndex = binarySearch(newList, key);

它應該工作。

這是一個返回原始列表索引的解決方案。 主要變化:當遞歸調用binarySearch時,將newList的偏移量(與list相比)添加到其結果中。 midPointValue > key此偏移量為零,因此無需添加任何內容。 如果midPointValue < key則偏移量為midPoint

public int binarySearch(ArrayList<Integer> list, int key){
  int foundAtIndex  = -1;
  int midPoint = list.size()/2;
  int midPointValue = list.get(midPoint);

  if(list.size() > 1){
    if(midPointValue == key){
      foundAtIndex = midPoint;
    }
    else if(midPointValue > key){
      ArrayList<Integer> newList = new ArrayList<Integer>();
      for(int i = 0; i < midPoint; i++){
        newList.add(list.get(i));
      }
      return binarySearch(newList, key);
    }
    else if(midPointValue < key){
      ArrayList<Integer> newList = new ArrayList<Integer>();
      for(int j = midPoint+1; j < list.size(); j++){
        newList.add(list.get(j));
      }
      return midPoint + binarySearch(newList, key);
    }
  }
  else if(list.size() == 1){
    if(list.get(0) == key){
      foundAtIndex = 0;
    }
  }
  //return the index where the key was found, or -1 if not found
  return foundAtIndex;
}

其他要點:

  • 在進行下一個遞歸調用之前,無需設置midPoint。
  • 在一個方法中有多個返回是完全合法的。 無需完全傳播結果。
  • midPointmidPointValuepoint有點多余。 Varialbe名稱太長,使代碼難以理解。
  • 最后,無需創建新列表並將元素從原始列表復制到該新列表。 您可以通過添加輔助方法,簡單地告訴該方法僅檢查原始列表的特定部分。

這是我編寫此方法的方法:

public int binarySearch(ArrayList<Integer> list, int key) {
  return binarySearch(list, key, 0, list.size());
}

public int binarySearch(ArrayList<Integer> list, int key, int begin, int end) {

  if(end <= begin) 
    return -1; // Range is empty => key wasn't found

  int mid = (begin + end) / 2;
  int midValue = list.get(mid);

  if(midValue == key) 
    return mid;
  else if(midValue < key) 
    return binarySearch(list, begin, mid);
  else
    return binarySearch(list, mid + 1, end);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM