我在将这两种算法结合在一起时遇到了麻烦。我被要求修改Binary Search
以返回元素应插入数组的索引。我被要求实施一个Binary Insertion Sort
,使用我的Binary Search
对随机生成的ints
数组进行排序。
我的Binary Search
按照预期的方式工作,每当我单独测试时返回正确的索引。我写了Binary Insertion Sort
来了解它是如何工作的,并让它也可以工作。一旦我将两者结合在一起,它就会破裂。我知道我在一起错误地实现它们,但我不确定我的问题在哪里。
这就是我所拥有的:
public class Assignment3
{
public static void main(String[] args)
{
int[] binary = { 1, 7, 4, 9, 10, 2, 6, 12, 3, 8, 5 };
ModifiedBinaryInsertionSort(binary);
}
static int ModifiedBinarySearch(int[] theArray, int theElement)
{
int leftIndex = 0;
int rightIndex = theArray.length - 1;
int middleIndex = 0;
while(leftIndex <= rightIndex)
{
middleIndex = (leftIndex + rightIndex) / 2;
if (theElement == theArray[middleIndex])
return middleIndex;
else if (theElement < theArray[middleIndex])
rightIndex = middleIndex - 1;
else
leftIndex = middleIndex + 1;
}
return middleIndex - 1;
}
static void ModifiedBinaryInsertionSort(int[] theArray)
{
int i = 0;
int[] returnArray = new int[theArray.length + 1];
for(i = 0; i < theArray.length; i++)
{
returnArray[ModifiedBinarySearch(theArray, theArray[i])] = theArray[i];
}
for(i = 0; i < theArray.length; i++)
{
System.out.print(returnArray[i] + " ");
}
}
}
我运行它时获得的返回值是1 0 0 0 0 2 0 0 3 5 12
。有什么建议吗?
更新:更新了ModifiedBinaryInsertionSort
static void ModifiedBinaryInsertionSort(int[] theArray)
{
int index = 0;
int element = 0;
int[] returnArray = new int[theArray.length];
for (int i = 1; i < theArray.lenght - 1; i++)
{
element = theArray[i];
index = ModifiedBinarySearch(theArray, 0, i, element);
returnArray[i] = element;
while (index >= 0 && theArray[index] > element)
{
theArray[index + 1] = theArray[index];
index = index - 1;
}
returnArray[index + 1] = element;
}
}
答案 0 :(得分:1)
插入排序的工作原理是,它创建一个新的空数组B,对于未排序数组A中的每个元素,它二进制搜索到目前为止已构建的B部分(从左到右),轮班B中位置右侧的所有元素选择一个并插入元素。因此,您在B中构建一个全时排序的数组,直到它是B的完整大小并包含A中的所有内容。 / p>
两件事:
一,二进制搜索应该能够采用int startOfArray和int endOfArray,并且它只会在这两点之间进行二进制搜索。这允许您仅考虑数组B中实际上是排序数组的部分。
两个,在插入之前,必须先将所有元素向右移动一步,然后再插入已经制作的间隙中。
答案 1 :(得分:1)
我意识到这已经过时了,但问题的答案是,或许有点不直观,“Middleindex - 1”在所有情况下都不会成为您的插入索引。 如果你在纸上遇到一些案例,问题就会变得明显。
我有一个解决此问题的扩展方法。要将它应用于您的情况,您将遍历现有列表,插入空的起始列表。
public static void BinaryInsert<TItem, TKey>(this IList<TItem> list, TItem item, Func<TItem, TKey> sortfFunc)
where TKey : IComparable
{
if (list == null)
throw new ArgumentNullException("list");
int min = 0;
int max = list.Count - 1;
int index = 0;
TKey insertKey = sortfFunc(item);
while (min <= max)
{
index = (max + min) >> 1;
TItem value = list[index];
TKey compKey = sortfFunc(value);
int result = compKey.CompareTo(insertKey);
if (result == 0)
break;
if (result > 0)
max = index - 1;
else
min = index + 1;
}
if (index <= 0)
index = 0;
else if (index >= list.Count)
index = list.Count;
else
if (sortfFunc(list[index]).CompareTo(insertKey) < 0)
++index;
list.Insert(index, item);
}
答案 2 :(得分:0)
老兄,我觉得你的代码存在严重问题。不幸的是,你错过了这个算法的果实(逻辑)。你在这里的神圣目标是首先获得指数,插入是一个蛋糕步行,但索引需要一些汗水。除非你尽力而且绝望,否则请不要看到这个算法。永不放弃,你已经知道逻辑,你的目标是在你身上找到它。如有任何错误,不符之处,请告诉我。快乐的编码!!
public class Insertion {
private int[] a;
int n;
int c;
public Insertion()
{
a = new int[10];
n=0;
}
int find(int key)
{
int lowerbound = 0;
int upperbound = n-1;
while(true)
{
c = (lowerbound + upperbound)/2;
if(n==0)
return 0;
if(lowerbound>=upperbound)
{
if(a[c]<key)
return c++;
else
return c;
}
if(a[c]>key && a[c-1]<key)
return c;
else if (a[c]<key && a[c+1]>key)
return c++;
else
{
if(a[c]>key)
upperbound = c-1;
else
lowerbound = c+1;
}
}
}
void insert(int key)
{
find(key);
for(int k=n;k>c;k--)
{
a[k]=a[k-1];
}
a[c]=key;
n++;
}
void display()
{
for(int i=0;i<10;i++)
{
System.out.println(a[i]);
}
}
public static void main(String[] args)
{
Insertion i=new Insertion();
i.insert(56);
i.insert(1);
i.insert(78);
i.insert(3);
i.insert(4);
i.insert(200);
i.insert(6);
i.insert(7);
i.insert(1000);
i.insert(9);
i.display();
}
}
答案 3 :(得分:0)
这是我使用二进制搜索对整数数组进行排序的方法。 它修改了作为参数传递的数组。
private boolean gridClick = false;
case R.id.list_click:
if(listClick) { // Check whether the tab is already clicked or not
Log.e("AlreadyClicked", "Test");
} else {
Log.e("ClickedFirstTime", "Test");
loadPost();
ivGrid.setVisibility(View.GONE); // Hiding grid recyclerview
ivList.setVisibility(View.VISIBLE); // showing list recyclerview
rvGrid.setVisibility(View.GONE); // Make grid recyclerview as gone
recyclerList.setVisibility(View.VISIBLE); // make listview as visible
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this); // Use separate layoutmanager for list recyclerview
recyclerList.setLayoutManager(mLayoutManager);
recyclerList.setItemAnimator(new DefaultItemAnimator());
recyclerList.setAdapter(friendsProfileUserPostitemsAdapter);
listClick = true;
}
break;