为什么二分查找是分而治之的算法?

发布于 2024-12-26 23:08:34 字数 164 浏览 2 评论 0 原文

考试时有人问我二分查找是否是分而治之的算法。我的答案是肯定的,因为你把问题分成了更小的子问题,直到得到你的结果。

但考官问其中的征服部分在哪里,我无法回答。他们也不同意这实际上是一种分而治之的算法。

但无论我在网上访问什么,它都说是这样,所以我想知道为什么,以及它的征服部分在哪里?

I was asked if a Binary Search is a divide and conquer algorithm at an exam. My answer was yes, because you divided the problem into smaller subproblems, until you reached your result.

But the examinators asked where the conquer part in it was, which I was unable to answer. They also disapproved that it actually was a divide and conquer algorithm.

But everywhere I go on the web, it says that it is, so I would like to know why, and where the conquer part of it is?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

梦与时光遇 2025-01-02 23:08:34

书上

Data Structures and Algorithm Analysis in Java (2nd Edition), by Mark Allen Weiss

说:D&C 算法应该有两个不相交的递归调用,就像 QuickSort 那样。

二分查找没有这个,尽管它可以递归实现。

The book:

Data Structures and Algorithm Analysis in Java (2nd Edition), by Mark Allen Weiss

Says that a D&C algorithm should have two disjoint recursive calls, just like QuickSort does.

Binary Search does not have this, even though it can be implemented recursively.

流心雨 2025-01-02 23:08:34

我认为这不是分而治之,请参阅http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm中的第一段

递归地将问题分解为两个或多个子问题
然后将它们组合起来给出解决方案

在二分搜索中,仍然只有一个问题,即每一步将数据减少一半,因此不需要结果的征服(合并)阶段。

I think it is not divide and conquer, see first paragraph in http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm

recursively breaking down a problem into two or more sub-problems
which are then combined to give a solution

In binary search there is still only one problem which does just reducing data by half every step, so no conquer (merging) phase of the results is needed.

回忆那么伤 2025-01-02 23:08:34

事实并非如此。

为了补充 @Kenci 的帖子,DnC 算法有一些通用/通用属性;他们:

  1. 将原始问题实例划分为一组较小的子实例;
  2. 独立求解每个子实例;
  3. 组合较小/独立的子实例解决方案来为较大/原始实例构建单个解决方案

二分搜索的问题在于,它真正生成一组独立的解决方案需要解决的子实例,按照步骤1;它只是通过永久丢弃它不感兴趣的部分来简化原始问题。换句话说,它只会减小问题的规模,而且也仅限于此。

DnC 算法不仅应该能够独立地识别/解决原始问题的较小子实例,而且还可以使用这组部分独立的解决方案为整个较大的问题实例“构建”单个解决方案。

G. Brassard、P. Bratley 的算法基础一书说道:

这可能是分而治之最简单的应用,事实上非常简单,严格来说,这是一个简化应用,而不是分而治之 :任何足够大的实例的解决方案都会减少为单个较小实例的解决方案,在本例中为一半大小。

第 226 页上的7.3 二分查找部分。

It isn't.

To complement @Kenci's post, DnC algorithms have a few general/common properties; they:

  1. divide the original problem instance into a set of smaller sub-instances of itself;
  2. independently solve each sub-instance;
  3. combine smaller/independent sub-instance solutions to build a single solution for the larger/original instance

The problem with Binary Search is that it does not really even generate a set of independent sub-instances to be solved, as per step 1; it only simplifies the original problem by permanently discarding sections it's not interested in. In other words, it only reduces the problem's size and that's as far as it ever goes.

A DnC algorithm is supposed to not only identify/solve the smaller sub-instances of the original problem independently of each other, but also use that set of partial independent solutions to "build up" a single solution for the larger problem instance as a whole.

The book Fundamentals of Algorithmics, G. Brassard, P. Bratley says the following (bold my emphasis, italics in original):

It is probably the simplest application of divide-and-conquer, so simple in fact that strictly speaking this is an application of simplification rather than divide-and-conquer: the solution to any sufficiently large instance is reduced to that of a single smaller one, in this case of half size.

Section 7.3 Binary Search on p.226.

望喜 2025-01-02 23:08:34

在分而治之的策略中:

1.问题被分成几个部分;

2.通过应用手头的算法来独立地攻击/解决这些部分中的每一个(大多数递归用于此目的);

3.然后将每个分区/划分的解决方案组合/合并在一起,以得出整个问题的最终解决方案(这属于征服

示例,快速排序,合并排序。

基本上,二分搜索算法只是在每次迭代中将其工作空间(大小为 n 的输入(有序)数组)分成两半。因此,它肯定会部署划分策略,结果,时间复杂度降低到O(lg n)。所以,这掩盖了其中的“划分”部分。

可以注意到,最终的解决方案是从最后一次比较中获得的,即当我们只剩下一个元素进行比较时。
二分查找不会合并或组合解决方案。

简而言之,二分搜索将问题(它必须解决的问题)的大小分成两半,但没有找到零散的解决方案,因此不需要合并解决方案发生!

我知道它有点太长了,但我希望它有帮助:)

你也可以从以下地方得到一些想法: https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/running-time-of-binary-search

我现在也意识到这个问题很久以前就发布了!
我的坏!

In a divide and conquer strategy :

1.Problem is divided into parts;

2.Each of these parts is attacked/solved independently, by applying the algorithm at hand (mostly recursion is used for this purpose) ;

3.And then the solutions of each partition/division and combined/merged together to arrive at the final solution to the problem as a whole (this comes under conquer)

Example, Quick sort, merge sort.

Basically, the binary search algorithm just divides its work space(input (ordered) array of size n) into half in each iteration. Therefore it is definitely deploying the divide strategy and as a result, the time complexity reduces down to O(lg n).So,this covers up the "divide" part of it.

As can be noticed, the final solution is obtained from the last comparison made, that is, when we are left with only one element for comparison.
Binary search does not merge or combine solution.

In short, binary search divides the size of the problem (on which it has to work) into halves but doesn't find the solution in bits and pieces and hence no need of merging the solution occurs!

I know it's a bit too lengthy but i hope it helps :)

Also you can get some idea from : https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/running-time-of-binary-search

Also i realised just now that this question was posted long back!
My bad!

我不在是我 2025-01-02 23:08:34

合并排序快速排序算法使用分而治之技术(因为有2个子问题)和二分搜索< /code> 属于减少和征服(因为有 1 个子问题)。

因此,二分查找实际上使用的是减少和征服技术,而不是分而治之技术。

来源:https://www.geeksforgeeks.org/decrease-and-conquer/

The Merge Sort and Quick Sort algorithms use the divide and conquer technique (because there are 2 sub-problems) and Binary Search comes under decrease and conquer (because there is 1 sub-problem).

Therefore, Binary Search actually uses the decrease and conquer technique and not the divide and conquer technique.

Source: https://www.geeksforgeeks.org/decrease-and-conquer/

关于从前 2025-01-02 23:08:34

显然,有些人认为二分搜索是一种分而治之的算法,而有些人则不然。我很快用谷歌搜索了三篇参考文献(似乎都与学术界有关),将其称为 D&C 算法:
http://www.cs.berkeley.edu/~vazirani/algorithms/chap2 .pdf
http://homepages.ius.edu/rwisman/C455/html /notes/Chapter2/DivConq.htm
http://www.csc.liv.ac.uk/ ~ped/teachadmin/algor/d_and_c.html

我认为 D&C 算法应该至少具有这三个阶段的前两个阶段是普遍共识:

  • 划分,即决定如何将整个问题分为子问题;
  • 征服,即独立解决每个子问题;
  • [可选]合并,即将独立计算的结果合并在一起。

第二阶段 - 征服 - 应该递归地应用相同的技术来解决子问题,通过划分为更小的子子问题等。然而,在实践中,通常使用一些阈值来限制递归方法,对于小尺寸问题不同的方法可能会更快。例如,当要排序的数组部分的大小变小时,快速排序实现通常使用例如冒泡排序。

第三阶段可能是空操作,在我看来,这并不会使算法失去 D&C 的资格。一个常见的例子是 for 循环的递归分解,其中所有迭代都纯粹使用独立的数据项(即没有任何形式的简化)。乍一看,它可能看起来没什么用,但事实上,它是一种非常强大的方法,例如并行执行循环,并被 Cilk 和英特尔的 TBB 等框架所利用。

回到最初的问题:让我们考虑一些实现该算法的代码(我使用 C++;抱歉,如果这不是您熟悉的语言):

int search( int value, int* a, int begin, int end ) {
  // end is one past the last element, i.e. [begin, end) is a half-open interval.
  if (begin < end)
  {
    int m = (begin+end)/2;
    if (value==a[m])
      return m;
    else if (value<a[m])
      return search(value, a, begin, m);
    else
      return search(value, a, m+1, end);
  }
  else // begin>=end, i.e. no valid array to search
    return -1;
}

这里除法部分​​是 int m = (begin+end)/2 ; 剩下的就是征服部分。该算法显式地以递归 D&C 形式编写,即使只采用其中一个分支。不过,它也可以写成循环形式:

int search( int value, int* a, int size ) {
  int begin=0, end=size;
  while( begin<end ) {
    int m = (begin+end)/2;
    if (value==a[m])
      return m;
    else if (value<a[m])
      end = m;
    else
      begin = m+1;
  }
  return -1;
}

我认为这是用循环实现二分查找的一种很常见的方式;我故意使用与递归示例中相同的变量名称,以便更容易看出共性。因此,我们可以说,计算中点是除法部分,而循环体的其余部分是征服部分。

但当然,如果你的审查员有不同的想法,可能很难让他们相信这是 D&C。

更新:只是有一个想法,如果我要开发 D&C 算法的通用框架实现,我肯定会使用二分搜索作为 API 适合性测试之一,以检查 API 是否足够强大且简洁。当然这并不能证明什么:)

Apparently some people consider binary search a divide-and-conquer algorithm, and some are not. I quickly googled three references (all seem related to academia) that call it a D&C algorithm:
http://www.cs.berkeley.edu/~vazirani/algorithms/chap2.pdf
http://homepages.ius.edu/rwisman/C455/html/notes/Chapter2/DivConq.htm
http://www.csc.liv.ac.uk/~ped/teachadmin/algor/d_and_c.html

I think it's common agreement that a D&C algorithm should have at least the first two phases of these three:

  • divide, i.e. decide how the whole problem is separated into sub-problems;
  • conquer, i.e. solve each of the sub-problems independently;
  • [optionally] combine, i.e. merge the results of independent computations together.

The second phase - conquer - should recursively apply the same technique to solve the subproblem by dividing into even smaller sub-sub-problems, and etc. In practice, however, often some threshold is used to limit the recursive approach, as for small size problems a different approach might be faster. For example, quick sort implementations often use e.g. bubble sort when the size of an array portion to sort becomes small.

The third phase might be a no-op, and in my opinion it does not disqualify an algorithm as D&C. A common example is recursive decomposition of a for-loop with all iterations working purely with independent data items (i.e. no reduction of any form). It might look useless at glance, but in fact it's very powerful way to e.g. execute the loop in parallel, and utilized by such frameworks as Cilk and Intel's TBB.

Returning to the original question: let's consider some code that implements the algorithm (I use C++; sorry if this is not the language you are comfortable with):

int search( int value, int* a, int begin, int end ) {
  // end is one past the last element, i.e. [begin, end) is a half-open interval.
  if (begin < end)
  {
    int m = (begin+end)/2;
    if (value==a[m])
      return m;
    else if (value<a[m])
      return search(value, a, begin, m);
    else
      return search(value, a, m+1, end);
  }
  else // begin>=end, i.e. no valid array to search
    return -1;
}

Here the divide part is int m = (begin+end)/2; and all the rest is the conquer part. The algorithm is explicitly written in a recursive D&C form, even though only one of the branches is taken. However, it can also be written in a loop form:

int search( int value, int* a, int size ) {
  int begin=0, end=size;
  while( begin<end ) {
    int m = (begin+end)/2;
    if (value==a[m])
      return m;
    else if (value<a[m])
      end = m;
    else
      begin = m+1;
  }
  return -1;
}

I think it's quite a common way to implement binary search with a loop; I deliberately used the same variable names as in the recursive example, so that commonality is easier to see. Therefore we might say that, again, calculating the midpoint is the divide part, and the rest of the loop body is the conquer part.

But of course if your examiners think differently, it might be hard to convince them it's D&C.

Update: just had a thought that if I were to develop a generic skeleton implementation of a D&C algorithm, I would certainly use binary search as one of API suitability tests to check whether the API is sufficiently powerful while also concise. Of course it does not prove anything :)

煮茶煮酒煮时光 2025-01-02 23:08:34

二分查找很难用分而治之的方法来描述,因为征服步骤并不明确。算法的结果是针在干草堆中的索引,纯 D&C 实现将返回针在最小干草堆中的索引(单元素列表中的 0),并且然后递归地添加在分割步骤中分割的较大干草堆中的偏移量。

伪代码解释:

function binary_search has arguments needle and haystack and returns index
    if haystack has size 1
       return 0
    else 
        divide haystack into upper and lower half
        if needle is smaller than smallest element of upper half
            return 0 + binary_search needle, lower half
        else
            return size of lower half + binary_search needle, upper half

加法(0 +下半部分的大小)是征服部分。大多数人通过提供更大列表中的索引作为参数来跳过它,因此它通常不容易获得。

Binary search is tricky to describe with divide-and-conquer because the conquering step is not explicit. The result of the algorithm is the index of the needle in the haystack, and a pure D&C implementation would return the index of the needle in the smallest haystack (0 in the one-element list) and then recursively add the offsets in the larger haystacks that were divided in the divison step.

Pseudocode to explain:

function binary_search has arguments needle and haystack and returns index
    if haystack has size 1
       return 0
    else 
        divide haystack into upper and lower half
        if needle is smaller than smallest element of upper half
            return 0 + binary_search needle, lower half
        else
            return size of lower half + binary_search needle, upper half

The addition (0 + or size of lower half) is the conquer part. Most people skip it by providing indices into a larger list as arguments, and thus it is often not readily available.

梦里泪两行 2025-01-02 23:08:34

划分部分当然是将集合分成两半。

征服部分是确定处理部分中是否存在搜索元素以及在处理部分的什么位置存在搜索元素。

The divide part is of course dividing the set into halves.

The conquer part is determining whether and on what position in the processed part there is a searched element.

自此以后,行同陌路 2025-01-02 23:08:34

计算机科学中的二分法是指在两个对立的选择之间、两个不同的选择之间进行选择。二分法是将一个整体分成恰好两个不重叠的部分,这意味着它是一个将整体分为两个部分的过程。它是将整体(或集合)划分为两个部分(子集),即:
1. 共同详尽:所有事物都必须属于某一部分或另一部分,并且
2. 互斥:没有任何东西可以同时属于两个部分。

分治法的工作原理是递归地将问题分解为两个或多个相同类型的子问题,直到这些问题变得足够简单,可以直接解决。

因此,二分搜索将每次迭代检查的项目数量减半,并确定是否有机会在该一半中找到“关键”项目,或者如果能够确定键不存在,则继续移动到另一半。由于该算法本质上是二分法,因此二分搜索将认为“密钥”必须位于一个部分中,直到它达到返回密钥丢失的退出条件。

Dichotomic in computer science refers to choosing between two antithetical choices, between two distinct alternatives. A dichotomy is any splitting of a whole into exactly two non-overlapping parts, meaning it is a procedure in which a whole is divided into two parts. It is a partition of a whole (or a set) into two parts (subsets) that are:
1. Jointly Exhaustive: everything must belong to one part or the other, and
2. Mutually Exclusive: nothing can belong simultaneously to both parts.

Divide and conquer works by recursively breaking down a problem into two or more sub-problems of the same type, until these become simple enough to be solved directly.

So the binary search halves the number of items to check with each iteration and determines if it has a chance of locating the "key" item in that half or moving on to the other half if it is able to determine keys absence. As the algorithm is dichotomic in nature so the binary search will believe that the "key" has to be in one part until it reaches the exit condition where it returns that the key is missing.

百合的盛世恋 2025-01-02 23:08:34

分而治之算法基于以下 3 个步骤:

  1. 分而
  2. 治之
  3. 组合

二分搜索问题可以定义为在排序数组 A[n] 中查找 x。
根据以下信息:

  1. 除:将 x 与中间比较 征服
  2. :在一个子数组中递归。 (在这个数组中查找x)
  3. 合并:没有必要。

Divide and Conquer algorithm is based on 3 step as follows:

  1. Divide
  2. Conquer
  3. Combine

Binary Search problem can be defined as finding x in the sorted array A[n].
According to this information:

  1. Divide: compare x with middle
  2. Conquer: Recurse in one sub array. (Finding x in this array)
  3. Combine: it is not necessary.
巴黎盛开的樱花 2025-01-02 23:08:34

正确的分而治之算法需要处理两个部分。

因此,很多人不会将二分搜索称为分而治之算法,它确实划分了问题,但丢弃了另一半。

但最有可能的是,你的考官只是想看看你如何争论。 (好)考试不是关于事实,而是关于当挑战超出原始材料时你如何反应。

所以恕我直言,正确的答案是:

嗯,从技术上讲,它只包含一个划分步骤,但只需要完成原始任务的一半,另一半已经轻松完成。

顺便说一句:QuickSort 有一个很好的变体,称为 QuickSelect,它实际上利用了这种差异来获得平均 O(n) 中值搜索算法。它就像快速排序 - 但只下降到它感兴趣的一半。

A proper divide and conquer algorithm will require both parts to be processed.

Therefore, many people will not call binary-search a divide and conquer algorithm, it does divide the problem, but discards the other half.

But most likely, your examiners just wanted to see how you argue. (Good) exams aren't about the facts, but about how you react when the challenge goes beyond the original material.

So IMHO the proper answer would have been:

Well, technically, it consists only of a divide step, but needs to conquer only half of the original task then, the other half is trivially done already.

BTW: there is a nice variation of QuickSort, called QuickSelect, which actually exploits this difference to obtain an on average O(n) median search algorithm. It's like QuickSort - but descends only into the half it is interested in.

简单气质女生网名 2025-01-02 23:08:34

二分查找不是分而治之的方法。这是一种减少和征服的方法。

在分而治之的方法中,每个子问题都必须对解决方案做出贡献,但在二分搜索中,所有细分都不会对解决方案做出贡献。我们分成两部分并丢弃一部分,因为我们知道该部分不存在解,只在一部分中寻找解。

Binary Search is not a divide and conquer approach. It is a decrease and conquer approach.

In divide and conquer approach, each subproblem must contribute to the solution but in binary search, all subdivision does not contribute to the solution. we divide into two parts and discard one part because we know that the solution does not exist in this part and look for the solution only in one part.

末が日狂欢 2025-01-02 23:08:34

非正式的定义或多或少是:将问题分成小问题。然后解决它们并将它们放在一起(征服)。解决实际上是决定下一步去哪里(左、右、找到元素)。

这里引用维基百科

“分而治之”这个名称有时也适用于将每个问题简化为一个子问题的算法,例如用于在排序列表中查找记录的二分搜索算法。

这表明,它不是[更新:误读了这句话:)]只是分而治之的一部分。

更新:
这篇文章对我来说很清楚。我很困惑,因为定义说你必须解决每个子问题。但是如果您知道不必继续搜索,您就解决了子问题。

The informal definition is more or less: Divide the problem into small problems. Then solve them and put them together (conquer). Solving is in fact deciding where to go next (left, right, element found).

Here a quote from wikipedia:

The name "divide and conquer" is sometimes applied also to algorithms that reduce each problem to only one subproblem, such as the binary search algorithm for finding a record in a sorted list.

This states, it's NOT [update: misread this phrase:)] only one part of divide and conquer.

Update:
This article made it clear for me. I was confused since the definition says you have to solve every sub problem. But you solved the sub problem if you know you don't have to keep on searching..

作死小能手 2025-01-02 23:08:34

二分搜索是一种分而治之的算法:

1)在分而治之算法中,我们尝试通过解决较小的子问题(分治部分)来解决问题,并使用该解决方案来构建更大问题的解决方案(征服)。

2)这里我们的问题是在排序数组中找到一个元素。我们可以通过解决类似的子问题来解决这个问题。 (我们在这里根据正在搜索的元素小于或大于中间元素的决定来创建子问题)。因此,一旦我们知道该元素不能确定存在于一半中,我们就可以在另一半中解决类似的子问题。

3)这样我们就递归了。

4)这里的征服部分只是将子问题返回的值返回到递归树的顶部

The Binary Search is a divide and conquer algorithm:

1) In Divide and Conquer algorithms, we try to solve a problem by solving a smaller sub problem (Divide part) and use the solution to build the solution for our bigger problem(Conquer).

2) Here our problem is to find an element in the sorted array. We can solve this by solving a similar sub problem. (We are creating sub problems here based on a decision that the element being searched is smaller or bigger than the middle element). Thus once we know that the element can not exist surely in one half, we solve a similar sub-problem in the the other half.

3) This way we recurse.

4) The conquer part here is just returning the value returned by the sub problem to the top the recursive tree

一杆小烟枪 2025-01-02 23:08:34

我认为这是减少与征服。

这是维基百科的引用。

“已提议使用“减少与征服”这个名称来代替
单子问题类”

http://en.wikipedia.org/wiki/Divide_and_conquer_algorithms#Decrease_and_conquer

根据我的理解,“征服”部分位于当找到二分搜索的目标元素时结束。“减少”部分正在减少搜索空间。

I think it is Decrease and Conquer.

Here is a quote from wikipedia.

"The name decrease and conquer has been proposed instead for the
single-subproblem class"

http://en.wikipedia.org/wiki/Divide_and_conquer_algorithms#Decrease_and_conquer

According to my understanding, "Conquer" part is at the end when you find the target element of the Binary search. The "Decrease" part is reducing the search space.

も让我眼熟你 2025-01-02 23:08:34

二元搜索和三元搜索算法基于减少和征服技术。因为,你没有除以问题,实际上你通过除以 2(三元搜索中的 3)来减少问题。

合并排序和快速排序算法可以作为分而治之技术的示例。您将问题分为两个子问题,并再次使用这些子问题的算法对数组进行排序。但是,您在二分搜索中丢弃了数组的一半。这意味着您减少数组的大小,而不是除法。

Binary Search and Ternary Search Algorithms are based on Decrease and Conquer technique. Because, you do not divide the problem, you actually decrease the problem by dividing by 2(3 in ternary search).

Merge Sort and Quick Sort Algorithms can be given as examples of Divide and Conquer technique. You divide the problem into two subproblems and use the algorithm for these subproblems again to sort an array. But, you discard the half of array in binary search. It means you DECREASE the size of array, not divide.

憧憬巴黎街头的黎明 2025-01-02 23:08:34

不,二分查找不是分而治之。是的,二分查找就是减法。我相信分而治之算法的效率为 O(n log(n)),而减法算法的效率为 O(log(n))。区别在于您是否需要评估数据拆分的两个部分。

No, binary search is not divide and conquer. Yes, binary search is decrease and conquer. I believe divide and conquer algorithms have an efficiency of O(n log(n)) while decrease and conquer algorithms have an efficiency of O(log(n)). The difference being whether or not you need to evaluate both parts of the split in data or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文