它的工作方式与您期望的一样。没问题。
public int find(long searchKey) {
int lowerBound = 0;
int upperBound = nElems - 1;
int currentIndex;
while(true) {
currentIndex = (lowerBound + upperBound) / 2;
if(a[currentIndex] == searchKey)
return currentIndex; // found it!
else if(lowerBound > upperBound)
return nElems; // can't find it
else { // so then divide range
if(a[currentIndex] < searchKey)
lowerBound = currentIndex + 1; // it's in upper half
else
upperBound = currentIndex - 1; // it's in lower half
} // end else divide range
} // end while loop
} // end find() method
这是使用线性搜索的原始insert()方法。很简单,对吧?
public void insert(long value) { // put element into array
int j;
for(j=0; j<nElems; j++) // find where it goes
if(a[j] > value) // (linear search)
break;
for(int k=nElems; k>j; k--) // move bigger ones up
a[k] = a[k-1];
a[j] = value; // insert it
nElems++; // increment size
} // end insert()
我需要修改insert()方法以使用find()方法的二进制搜索算法。这是我到目前为止所提出的。显然它有问题,但我似乎无法找到问题。它根本不起作用,即不执行插入:
public int insertBS(long value) {
int lowerBound = 0;
int upperBound = nElems - 1;
int curIn;
while(true) {
curIn = (lowerBound + upperBound) / 2;
if(a[curIn] == value)
return curIn;
else if(lowerBound > upperBound)
return nElems;
else {
if(a[curIn] < value)
lowerBound = curIn + 1;
else
upperBound = curIn - 1;
}
for(int k=nElems; k>curIn; k--) // move bigger one up
a[k] = a[k-1];
a[curIn] = value;
nElems++;
}
}
语言:Java
使用有序数组。
答案 0 :(得分:5)
嗯,很明显为什么没有插入值,这是因为你从未插入过值。一旦找到要插入的位置索引,只需从函数返回而不做任何操作。
答案 1 :(得分:2)
您需要执行二进制搜索以在移动元素之前查找插入索引。在上一个代码段中,您尝试使用变量curIn
在二进制搜索完成之前移动while
循环内的元素。尝试将for
循环移到while
循环之外。
答案 2 :(得分:2)
public int insertBS(long value) {
int curIn = find(value); // find where it goes (binary search)
for(int k=nElems; k>curIn; k--) // move bigger one up
a[k] = a[k-1];
a[j] = value; // insert it
nElems++; // increment size
}
这样,当您优化/更改查找功能时,插入功能也会更快!
作为旁注,我认为你的find函数不会像你所写的那样给你预期的行为。如果你有一个[0,1,4,5,9]的列表,我搜索7,我将得到一个nElems(5)的索引,这可能会被误解为索引0到4的值都小于7.似乎有点不稳定。
答案 3 :(得分:0)
int lowerBound = 0;
int upperBound = nElems-1;
int pos = 0;
if(value < a[0])
pos=0;
else if(nElems>0 && value>a[upperBound])
pos=nElems;
else
{
while(nElems>1)
{
int j = (lowerBound + upperBound ) / 2;
if(upperBound - lowerBound ==0)
{
pos = lowerBound+1;
break; // found it
}
else if(upperBound - lowerBound ==1)
{
pos=upperBound; //lo encontre
break;
}
else // divide range
{
if(a[j] < value)
lowerBound = j + 1; // it's in upper half
else
upperBound = j - 1; // it's in lower half
} // end else divide range
}
}
for(int k=nElems; k>pos; k--) // move higher ones up
a[k] = a[k-1];
a[pos] = value; // insert it
nElems++; // increment size