【问题标题】:Given a sorted array of n elements, write a function to search a given element x in array给定一个有 n 个元素的排序数组,编写一个函数来搜索数组中的给定元素 x
【发布时间】:2019-10-12 20:49:02
【问题描述】:

问题解决:给定一个包含 n 个元素的排序数组,编写一个函数来搜索数组中的给定元素 x。

$在给定的排序数组中寻找一个元素。

$查找数字的第一次或最后一次出现。

【问题讨论】:

  • 真正的问题是什么?
  • 我的猜测是为什么这并不总是有效。如果您调用第一个Exists 以在数组[0, 1] 中找到值1,我认为它会错误地返回-1。由于我正在使用手机,因此无法检查或提供帮助
  • @Knoop 我检查过了,它工作正常
  • @WaelMourad 你是对的我读错了。所以基本上这个问题根本不是问题,而是尝试在 stackoverflow 上写博客?

标签: c# data-structures binary-search array-algorithms


【解决方案1】:

算法:二分搜索:

问题解决:给定一个有 n 个元素的排序数组,编写一个函数来搜索数组中的给定元素 x。

一个简单的方法是做线性搜索。上述算法的时间复杂度是O(n)。 执行相同任务的另一种方法是使用二分搜索。

二分搜索: 通过重复将搜索间隔分成两半来搜索排序数组。 从覆盖整个数组的间隔开始。 如果搜索键的值小于区间中间的项,则将区间缩小到下半部分。 否则将其缩小到上半部分。反复检查,直到找到值或区间为空。

...

二分查找适用于已排序的数组。该值与数组的中间元素进行比较。 如果未找到相等,则消除其中不存在值的一半。 同理,搜索另一半部分。

二分查找的思想是利用数组排序的信息,将时间复杂度降低到O(Log n)。

我们基本上在一次比较之后就忽略了一半的元素:

  1. 将 x 与中间元素进行比较。
  2. 如果 x 与中间元素匹配,我们返回中间索引。
  3. Else 如果 x 大于中间元素,则 x 只能位于中间元素之后的右半子数组中。所以我们在右半边重复。
  4. Else(x 更小)在左半边重复出现。

   public class BinarySearch
   {
    #region helpers.

    /// <summary>
    /// Returns index of x if it is present in int[], else return -1,
    /// </summary>
    /// <param name="array">array of sorted numbers</param>
    /// <param name="l">start index</param>
    /// <param name="r">end index</param>
    /// <param name="x">searched number</param>
    /// <returns>index of x</returns>
    public static int Exist(int[] array, int l, int r, int x)
    {
        while (l <= r)
        {
            int med = (l + r) / 2;
            // Check if x is present at mid
            if (x == array[med])
                return med;
            // If x is smaller, ignore right half
            if (x < array[med])
                r = (med - 1);
            // If x greater, ignore left half
            else
                l = (med + 1);
        }
        return -1;
    }

    /// <summary>
    /// Returns index of first or last occurrence of a number if it is 
        present in int[], else return -1,    
    /// </summary>
    /// <param name="array">array of sorted numbers</param>
    /// <param name="l">start index</param>
    /// <param name="r">end index</param>
    /// <param name="x">searched number</param>
    /// <param name="first">Boolean: true if searching first occurrence 
            or false if last</param>
    /// <returns>index of x</returns>
    public static int Exist(int[] array, int l, int r, int x, bool first)
    {
        int result = -1;
        while (l <= r)
        {
            int med = (l + r) / 2;
            // Check if x is present at mid
            if (x == array[med])
            {
                result = med;
                if (first)
                    r = (med - 1); //ignore right half
                else
                    l = (med + 1); //ignore left half
            }
            else if (x < array[med])
                r = (med - 1);
            else
                l = (med + 1);
        }
        return result;
    }
    #endregion
}

...

class Program
{
    #region props.
    public BinarySearch BinarySearch { get; set; }        
    #endregion
    #region cst.
    public Program()
    {
        this.BinarySearch = new BinarySearch();
    }
    #endregion

    #region publics
    public static void Main()
    {
        //int[] array = { 2, 3, 4, 10, 40 };
        //int count = array.Length - 1;
        //var result = BinarySearch.Exist(array, 0, count, 4); 

        int[] array = { 2, 10, 10, 10, 40 };
        int count = array.Length - 1;
        var result = BinarySearch.Exist(array, 0, count, 40, false);

        Console.WriteLine(result == -1 ? "Element not present" : 
         $"Element 
        found at index {result}");
        Console.ReadKey();                      
    } 
    #endregion
}

【讨论】:

  • 其中一些内容似乎是从互联网上复制而来的(例如here)。不注明出处的复制是抄袭,这是被禁止的。
猜你喜欢
  • 2019-11-23
  • 2014-04-19
  • 2014-03-10
  • 2021-11-19
  • 1970-01-01
  • 2012-03-18
  • 2013-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多