二进制/顺序搜索
Posted
技术标签:
【中文标题】二进制/顺序搜索【英文标题】:Binary/Sequential Searches 【发布时间】:2011-11-09 04:07:03 【问题描述】:我正在尝试编写一个程序,该程序在一个名为 items
的数组中执行顺序搜索和二进制搜索,该数组有 10000 个随机排序的 int
值。名为targets
的第二个数组加载了1000 个int
值(来自items
数组的500 个值和不在items
数组中的500 个值)。
基本上,搜索需要通过 items 数组来查找 targets
数组中的 int
值。这是我的代码:
import java.util.*;
// Loads two arrays with integers
// Searches the arrays using sequential search and binary search
// Compares the time for each search
public class Searches
private int items[], targets[];
public Searches()
this.items = new int[10000];
this.targets = new int[1000];
public void loadItemsAndTargets()
int nextValue = 100;
int index = 0;
Random generator = new Random(1);
items[0] = nextValue;
/* load the items array with items to be searched through */
for (index = 1; index < items.length; index++)
nextValue = nextValue + generator.nextInt(100);
items[index]= nextValue;
/* load the targets array with target values that will be searched for within
* array items, and target values that are not within array items
*/
index = 0;
while (index < targets.length)
targets[index] = items[index*10];
targets[index+1] = generator.nextInt(100);
index = index + 2;
public int sequentialSearch(int target)
/* Using the sequential search algorithm, search the items array for the target value passed
* If found, return the index in the items array, otherwise return -1
*/
this.loadItemsAndTargets();
int key = target;
int index;
boolean found = false;
index = 0;
while ((!found) && (index < items.length))
if (key == target)
found = true;
else
index = index + 1;
if (!found)
index = -1;
return index;
public int binarySearch(int target)
/* Using the binary search algorithm, search the items array for the target value passed
* If found, return the index in the items array, otherwise return -1
*/
this.loadItemsAndTargets();
target = targets.length;
int key = target;
boolean found = false;
int guess = 0;
int low = 0;
int high = items.length - 1;
while ((!found) && (low < high))
guess = (high+low)/2;
if (key == items[guess])
found = true;
else if (key < items[guess])
high = guess - 1;
else
low = guess + 1;
if (!found)
return - 1;
return guess;
public static void main(String[] args)
int index = 0;
Searches searcher = new Searches();
searcher.loadItemsAndTargets();
/* call the method that searches array items
* for each of the values in array targets
* using the sequential search algorithm
* print the approximate elapsed time in milliseconds
* For the FIRST FIVE searches print out the index
* where target value was found or print -1 if it was not found
*/
long startTimeSequential;
startTimeSequential = System.currentTimeMillis();
System.out.println(searcher.sequentialSearch(index));
long endTimeSequential;
endTimeSequential = System.currentTimeMillis();
long totalTimeSequential;
totalTimeSequential = endTimeSequential-startTimeSequential;
System.out.println("sequential search time: " + totalTimeSequential + " milliseconds");
/* call the method that searches array items
* for each of the values in array targets
* using the binary search algorithm
* print the approximate elapsed time in milliseconds
* For the FIRST FIVE searches print out the index
* where target value was found or print -1 if it was not found
*/
long startTimeBinary;
startTimeBinary = System.currentTimeMillis();
System.out.println(searcher.binarySearch(index));
long endTimeBinary;
endTimeBinary = System.currentTimeMillis();
long totalTimeBinary;
totalTimeBinary = endTimeBinary - startTimeBinary;
System.out.println("binary search time: " + totalTimeBinary + " milliseconds");
编辑:输出应该是这样 >
395
986
-1
14
-1
顺序搜索时间:40 毫秒
395
986
-1
14
-1
二分查找时间:0 毫秒
【问题讨论】:
【参考方案1】:您的 sequentialSearch 完全错误,您甚至没有访问其中的数组。
您的两种搜索方法都调用 loadItemsAndTargets。它应该只被调用一次
binarySearch 仅适用于排序数组。您的数组未排序。
即使你纠正了所有这些错误。请注意,您的数组将包含重复项。因此,如果尝试比较 sequentialSearch 和 binarySearch 之间的索引,它们可能不匹配,除非您的 binarySearch 返回 下限
【讨论】:
我忘了提...我在一个初学者的java课上。我完全被困在做什么...... 在寻求帮助之前,您必须先尝试一下。你有什么问题? 我更改了代码,没有在 binarySearch 方法中调用 loadItemsAndArray 方法。然后我尝试使用 Array.sort 对数组进行排序,但它给了我一个编译器错误,说 sort is undefined for type Array... 哦,好吧,所以在 binarySearch 方法中,我把 Arrays.sort(items);和 Arrays.sort(targets);。没有编译器错误,但我在正确的轨道上吗? 是的......一旦数组被排序。首先正确地进行顺序搜索。将项目和目标的数量从 10000 、 1000 减少,以便您可以调试并查看发生了什么【参考方案2】:有时,如果您对手头的搜索技术有很强的掌握,编写代码会更容易。考虑到这一点,我将重复您可能听到的内容,以防没有很好地解释。
顺序搜索很简单:
1. Set the starting index just before the beginning.
2. If there is a "next" item, check the next item to see if it matches.
2a. If it does match you found the item in your collection.
2b. If it does not match update the starting index to the item you just checked and continue at step 2.
3. If there is no next item, then you searched everything without finding your item.
二分查找也很简单:
1. If the unsearched part of your list is empty, then determine you didn't find the item.
2. If the unsearched part of your list is just one element, then check the element to see if it matches the lookup item.
2a. If id does match, you found the item in your list.
2b. If it does not match, the item isn't in your list.
3. If the unsearched part of your list is more than one element, find the element closest to the middle. It is ok to divide two element lists like 2, 4 into 2 4 where 4 is the middle.
3a. If the middle matches the lookup item, you found the item in your list.
3b. If the middle is larger than the lookup item, select the "smaller" side list and repeat the process.
3c. If the middle is smaller than the lookup item, select the "larger" side list and repeat the process.
顺序搜索的优点是最终会找到您的项目,即使列表未排序。二进制搜索的优点是您会更快地找到您的项目,但必须对列表进行排序。例如,一百万个项目列表将平均进行 50 万次比较才能通过顺序搜索找到一个项目;但是,二分查找只需要进行大约 20 次比较。这是因为二分查找中的每次比较都会丢掉剩余的一半可能性,而顺序查找中的每次比较只会丢掉一种可能性。
【讨论】:
请注意,在您的顺序搜索中,您首先将键设置为等于目标。稍后您检查它们是否相等以确定是否找到该项目。将这两件事按此顺序放在一起可以找到所有内容,即使这些项目不在列表中!以上是关于二进制/顺序搜索的主要内容,如果未能解决你的问题,请参考以下文章
用一张表来存储数据状态,并且可以进行多状态精确查询;使用二进制来表示数据状态,并且是可以无顺序的状态;解决使用中间表来存储数据的多状态;数据状态还可以这么玩;