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

ylamdve6  于 2021-06-30  发布在  Java
关注(0)|答案(4)|浏览(526)

我很难把这两种算法结合起来。我被要求修改 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;
    }
}
wdebmtf2

wdebmtf21#

下面是我使用二进制搜索对整数数组排序的方法。它修改作为参数传递的数组。

public static void binaryInsertionSort(int[] a) {
    if (a.length < 2)
        return;
    for (int i = 1; i < a.length; i++) {
        int lowIndex = 0;
        int highIndex = i;
        int b = a[i];

        //while loop for binary search
        while(lowIndex < highIndex) {
            int middle = lowIndex + (highIndex - lowIndex)/2; //avoid int overflow
            if (b >= a[middle]) {
                lowIndex = middle+1;
            }
            else {
                highIndex = middle;
            }
        }
        //replace elements of array
        System.arraycopy(a, lowIndex, a, lowIndex+1, i-lowIndex);
        a[lowIndex] = b;
    }
}
wsxa1bj1

wsxa1bj12#

伙计,我觉得你的代码有点问题。不幸的是,你错过了这个算法的成果(逻辑)。你在这里的神圣目标是首先得到索引,插入是小菜一碟,但索引需要一些汗水。请不要看到这个算法,除非你给你最好的和绝望的。永远不要放弃,你已经知道了逻辑,你的目标是在你身上找到它。请让我知道任何错误,差异等快乐编码!!

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();
}

}

of1yzvn4

of1yzvn43#

插入排序的工作原理是,它创建一个新的空数组b,对于未排序数组a中的每个元素,它将二进制搜索到迄今为止已构建的b部分(从左到右),将所有元素移到b中位置的右侧,然后选择一个右侧并将元素插入。所以你一直在b中建立一个排序数组,直到它是b的全部大小并且包含a中的所有内容。
两件事:
首先,二进制搜索应该能够获取一个int startofarray和一个int endofarray,并且它只能在这两点之间进行二进制搜索。这允许您只考虑数组b中实际是排序数组的部分。
第二,在插入之前,必须将所有元素向右移动一个元素,然后才能插入到所做的间隙中。

yfjy0ee7

yfjy0ee74#

我知道这很古老,但问题的答案是,也许有点不直观,“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);
    }

相关问题