二进制搜索已排序的数组

时间:2011-11-09 15:52:54

标签: c# arrays binary-search

我正在尝试使用此二进制搜索代码搜索降序排序数组。然而,在我对它进行排序并尝试搜索之后,它不会带来任何结果,只是一个永远不会消失的加载图标就好像它有一个无限循环。我不确定问题是什么,因为代码看起来合乎逻辑。

这是带有4.0框架的aspx,c#。提前谢谢!

    protected void Button2_Click(object sender, EventArgs e)
    {
        String item = TextBox1.Text;
        int target = Convert.ToInt16(item);
        int mid, first = 0, last = mynumbers.Length - 1;

        //for a sorted array with descending values
        while (first<=last)
        {
            mid = (first + last) / 2;
            if (target < mynumbers[mid])
                first = mid + 1;
            if (target > mynumbers[mid])
                last = mid - 1;
            else
                Label11.Text = "Target " + item + " was found at index " + mynumbers[mid];

        }

7 个答案:

答案 0 :(得分:20)

Array类中有二进制搜索:

int index = Array.BinarySearch(mynumbers, target);

对于降序,可以使用ReverseComparer轻松完成,这很容易写成:

    public class ReverseComparer<T> : IComparer<T>
    {
        public int Compare(T x, T y)
        {
            return Comparer<T>.Default.Compare(y, x);
        }
    }

然后:

int index = Array.BinarySearch(numbers, 7, new ReverseComparer<int>());

如果这是学术练习,您必须使用自定义搜索,当然,这不适用。如果它必须是一个类的自定义算法,那么问题是你必须在找到时突破循环,索引位于mid,而不是mynumbers[mid]

    //for a sorted array with descending values
    while (first<=last)
    {
        mid = (first + last) / 2;

        if (target < mynumbers[mid])
        {
            first = mid + 1;
        }

        if (target > mynumbers[mid])
        {
            last = mid - 1;
        }

        else
        {
            // the index is mid, not mynumbers[mid], and you need to break here
            // once found or it's an infinite loop once it finds it.
            Label11.Text = "Target " + item + " was found at index " + mid;
            break;
        }
    }

实际上,我可能会设置一个bool标志来保持算法的纯净,而不是将find与输出问题混合在一起,这也可以让你更容易分辨出如果你没有找到退出循环的话:< / p>

    bool found = false;

    //for a sorted array with descending values
    while (!found && first<=last)
    {
        mid = (first + last) / 2;

        if (target < mynumbers[mid])
        {
            first = mid + 1;
        }

        if (target > mynumbers[mid])
        {
            last = mid - 1;
        }

        else
        {
            // You need to stop here once found or it's an infinite loop once it finds it.
            found = true;
        }
    }

    Label11.Text = found 
        ? "Item " + item + " was found at position " + mid
        : "Item " + item + " was not found";

答案 1 :(得分:1)

在黑暗中拍摄:

if (target < mynumbers[mid]) 
   first = mid + 1; 
else if (target > mynumbers[mid]) 
   last = mid - 1; 
else 
{
    ....
    break;
}

我怀疑你在mid + 1和mid-1之间来回弹跳

答案 2 :(得分:0)

这是正确的:

  

如果target< mynumbers[mid]那么你必须持续到1月中旬,   因为我们必须在较低的范围内搜索,即从第一个到第一个中期

while (first<=last)
        {
            mid = (first + last) / 2;
            if (target == mynumbers[mid])
            Label11.Text = "Target " + item + " was found at index " + mynumbers[mid];

            else if (target < mynumbers[mid])
                last = mid - 1;
            else (target > mynumbers[mid])
                first = mid + 1;

            }

答案 3 :(得分:0)

//this works fine with these Test cases    
// has to check if (target == mynumbers[mid])    
// this is for an array with ascending order.
class Program
{

    static void Main(string[] args)
    {
        // TEST cases:
        // for 8: item 8 was not found
        // for 4: item 4 found at Position 3
        // for 1: item 1 found at position 0
        // for 0: item 0 was not found


        int target =8;
        int searchkey = target;

        int[] mynumbers = { 1, 2, 3, 4, 5 };

        int mid=0, first = 0, last = mynumbers.Length - 1;

        bool found = false;

        //for a sorted array with ascending values
        while (!found && first <= last)
        {
            mid = (first + last) / 2;

            if (target == mynumbers[mid])
                found = true;
            else
            {

                if (target > mynumbers[mid])
                {
                    first = mid + 1;
                }

                if (target < mynumbers[mid])
                {
                    last = mid - 1;
                }

            }

        }

        String foundmsg = found
            ? "Item " + searchkey + " was found at position " + mid
            : "Item " + searchkey + " was not found";
        Console.WriteLine(foundmsg);
     }
}

答案 4 :(得分:0)

它为我工作

public static int search(int[] arr, int value)
{
    Debug.Assert(arr.Length>0);
    var left = 0;
    var right = arr.Length - 1;

    while (((right - left)/2) > 0)
    {
        var middle = left + (right - left)/2;
        if (arr[middle] < value)
            left = middle + 1;
        else
            right = middle;
    }
    return arr[left] >= value ? left : right;
}

答案 5 :(得分:0)

        int num = 2;
        int[] value = { 1, 2, 3, 4, 5, 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
        int s = 0;
        int e = value.Length - 1;
        int m = (s + e) / 2;
        bool find = false;
        do
        {
            if (value[m] == num)
            {
                Console.WriteLine("We have found the given number");
                find = true;
            }
            else if (num < value[m])
            {
                e = m - 1;
            }
            else 
            {
                s = m + 1;
            }
            m = (s + e) / 2;
        } while (find != true);

答案 6 :(得分:-1)

public static object BinnarySearch(int[] array,int SearchKey)
    {
        int min = 0;
        int max = array.Length - 1;
        while (min <= max)
        {
            int mid = (min + max) / 2;
            if (SearchKey == array[mid])
            {
                return mid;
            }
            else if (SearchKey < array[mid])
            {
                max = mid - 1;
            }
            else
                min = mid + 1;
        }
        return "Not Found";
    }