在Java中使用二进制搜索实现二进制插入排序

时间:2013-06-06 02:56:24

标签: java algorithm binary-search insertion-sort

我在将这两种算法结合在一起时遇到了麻烦。我被要求修改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;
    }
}

4 个答案:

答案 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;