QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2894|回复: 0
打印 上一主题 下一主题

[讨论]一道分治法的题目,仅供参考

[复制链接]
字体大小: 正常 放大
lllaaa        

2

主题

2

听众

27

积分

升级  23.16%

该用户从未签到

新人进步奖

跳转到指定楼层
1#
发表于 2005-9-29 19:02 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
< ><FONT face="Times New Roman">2-2</FONT>、下面的<FONT face="Times New Roman">7</FONT>个算法与本章中的二分搜索算法<FONT face="Times New Roman">binarySearch</FONT>略有不同。请判断这<FONT face="Times New Roman">7</FONT>个算法的正确性。如果算法不正确,请说明错误产生的原因。如果算法正确,请给出算法的正确性证明。</P>" Q. f  {6 ~1 ~- b9 A! F, W$ [+ I
< ><FONT face="Times New Roman">public static int binarySearch1(int[] a, int x, int n)</FONT></P>
" \$ S0 Z' }0 D2 y2 I$ D< ><FONT face="Times New Roman">{</FONT></P>" x* O% Z* T& y) W
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>
0 F5 o. w/ j; R: F< ><FONT face="Times New Roman">              while(left &lt;= right)</FONT></P>
$ a! t0 q6 G5 e8 \) T5 }% B, l< ><FONT face="Times New Roman">{</FONT></P>
+ K0 D0 f2 B, u! b" B< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
0 u, m; y* l" N< ><FONT face="Times New Roman">   if(x == a[middle]) return middle;</FONT></P>
4 _" G0 Q1 l9 _# \6 e1 w2 f< ><FONT face="Times New Roman">   if(x &gt; a[middle]) left = middle;</FONT></P>% v2 L1 m4 b+ C& E
< ><FONT face="Times New Roman">   else right = middle;</FONT></P>
3 w- ^. A- C, g* O  X' E  U& k< ><FONT face="Times New Roman">}//while</FONT></P>
, T  |9 e- P% K8 N< ><FONT face="Times New Roman">return –1;</FONT></P>1 j" }  B( I9 ]( a" V) }. L
< ><FONT face="Times New Roman">}</FONT></P>0 B0 f* X( t( K  V( B7 g' D
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>+ b7 U  W/ J3 f
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>) i8 ^* ^, V! M
< ><FONT face="Times New Roman">public static int binarySearch2(int[] a, int x, int n)</FONT></P>9 ?. i3 B) w2 s& h% S7 s+ i$ d
< ><FONT face="Times New Roman">{</FONT></P>1 @: A) P* n: f" F; l$ l
< ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>; y5 x+ w, R& \! l
< ><FONT face="Times New Roman">              while(left &lt; right-1)</FONT></P>
( Y% n+ A* ]4 n0 J/ e< ><FONT face="Times New Roman">{</FONT></P>, W4 s/ X) s7 _2 C3 S
< ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>& H) Y7 t9 v; c: J1 d0 r
< ><FONT face="Times New Roman">   if(x &lt; a[middle]) right = middle;</FONT></P>
* h+ u* `- \0 Q& |. y< ><FONT face="Times New Roman">   else left = middle;</FONT></P># l$ D) y% P* `: {4 R$ p
< ><FONT face="Times New Roman">}//while</FONT></P>
/ ]0 N( o+ D( p4 ~< ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
# Q4 b7 p( V: y, K9 `8 l< ><FONT face="Times New Roman">else return –1;</FONT></P>
' T8 k/ }/ C8 ^: f* o2 O< ><FONT face="Times New Roman">}</FONT></P># Z/ {" p; j- d, s0 U8 d7 R" D7 t
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- Q5 m9 N2 C( y. h
< ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>5 {6 U9 h( O( R3 {9 U5 M+ q
< ><FONT face="Times New Roman">public static int binarySearch3(int[] a, int x, int n)</FONT></P>$ p" W/ c& |$ F# u: W
<P ><FONT face="Times New Roman">{</FONT></P># ?3 s* w! [/ V8 }# l! }" s; ^
<P ><FONT face="Times New Roman">              int left = 0, right = n-1;</FONT></P>8 [+ I! l: E) R' y
<P ><FONT face="Times New Roman">              while(left+1 != right)</FONT></P>
! @1 s- Q- R& O3 }<P ><FONT face="Times New Roman">{</FONT></P>9 N$ p1 j: F7 ~: _
<P ><FONT face="Times New Roman">   int middle = (left + right) / 2;</FONT></P>
2 h* t; i3 S( K& c<P ><FONT face="Times New Roman">   if(x &gt;= a[middle]) left = middle;</FONT></P>: a6 M8 b+ i: ^$ W8 t0 W
<P ><FONT face="Times New Roman">   else right = middle;</FONT></P>7 _' y' q* d3 I( i" ~3 L
<P ><FONT face="Times New Roman">}//while</FONT></P>/ [: t$ I  G6 h, j; N
<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>
5 o" L9 ]8 H/ d* z4 C* f<P ><FONT face="Times New Roman">else return –1;</FONT></P>. x9 |, a( j/ ?( V
<P ><FONT face="Times New Roman">}</FONT></P>
( Z. A" X' T! J<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
- t. Z( _' U8 }! P<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>- S0 m- C, ^0 ~3 g) C5 a+ E4 V
<P ><FONT face="Times New Roman">public static int binarySearch4(int[] a, int x, int n)</FONT></P>
, f% P5 D, Y& T! l# n<P ><FONT face="Times New Roman">{</FONT></P>0 D* A& y/ G7 E0 k
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P># k$ O8 c% j7 y4 J# g
<P ><FONT face="Times New Roman">              {</FONT></P>
% m$ c( \% w4 Z! s7 A<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>
1 [% i9 {: A' M2 x$ U8 C<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>/ D7 V' Y  m7 M* ^1 b
<P ><FONT face="Times New Roman">              {</FONT></P>: d/ k0 W) R: K$ R" B$ d
<P ><FONT face="Times New Roman">          int middle = (left + right) / 2;</FONT></P>9 Z1 {+ T9 q- N5 Z5 P
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
5 I7 G+ v* f- b; l5 }0 z3 w<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
  r' d2 _  G; D<P ><FONT face="Times New Roman">}//while</FONT></P>
8 k- H# F' O( M* i/ N- K<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>, X4 c2 {/ g6 H/ S9 k& c
<P ><FONT face="Times New Roman">}//if</FONT></P>% [7 N* t2 P! B, G9 ~, {; C# ~
<P ><FONT face="Times New Roman">return –1;</FONT></P>; ~4 A+ x! q: @! t; g% W
<P ><FONT face="Times New Roman">}</FONT></P>
  T: l- N5 r7 F# {0 M: U/ K/ _* c<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
0 G0 r0 p9 T6 o. \7 @, _<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
) m1 _9 Q: y8 N( f<P ><FONT face="Times New Roman">public static int binarySearch5(int[] a, int x, int n)</FONT></P>! P- ?! T$ {% g8 e6 n
<P ><FONT face="Times New Roman">{</FONT></P>
9 ~7 H$ x) H* t<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>2 y8 e; H; E& y. h
<P ><FONT face="Times New Roman">              {</FONT></P>
5 }! u, k9 L' A) @<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>: T/ o8 {/ h% D; {& }
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>; w; _, S; l7 X
<P ><FONT face="Times New Roman">              {</FONT></P>& @4 t8 u/ d4 K* M$ p' @3 e5 T# C" w
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>1 D& E' h6 G) C8 Y. z7 R! e1 T7 U
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
$ V+ q. W: {) X<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
+ W8 E  i  Q: H2 f<P ><FONT face="Times New Roman">}//while</FONT></P>
4 `( ?; [* v5 ^<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>3 U+ f6 u) y% u7 F, K1 c" i& I, D
<P ><FONT face="Times New Roman">}//if</FONT></P>5 [7 F0 S# Y3 [7 ?- \5 T
<P ><FONT face="Times New Roman">return –1;</FONT></P>9 {- b* J' t) F6 }- k- P
<P ><FONT face="Times New Roman">}</FONT></P>% U# q1 z$ k, Q- f* C$ ^" r/ x
<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
! v% P' ^- z6 w5 X6 O* l" m& F<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
% J2 ?* d7 T# J6 a9 ?0 Z<P ><FONT face="Times New Roman">public static int binarySearch6(int[] a, int x, int n)</FONT></P>  E) i5 W, V3 `0 R  M
<P ><FONT face="Times New Roman">{</FONT></P>
( T' E3 R5 w$ M6 {, T# x<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>4 k: I9 m+ A! v/ F; M
<P ><FONT face="Times New Roman">              {</FONT></P>
5 Z4 v6 Y: b+ s3 M% x. V+ {8 y$ j; t<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P># b; x1 Q+ X- |
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>. I6 y+ ]1 h7 u- J8 f) u# _$ H' t
<P ><FONT face="Times New Roman">              {</FONT></P>8 y) n+ U; c. ]' C% z
<P ><FONT face="Times New Roman">          int middle = (left + right + 1) / 2;</FONT></P>: k" v. {# h& ~! F/ `8 D
<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle - 1;</FONT></P>
- o* o5 N9 F. U- D4 ]$ H<P ><FONT face="Times New Roman">else left = middle + 1;</FONT></P>
9 {8 S% `+ [+ m<P ><FONT face="Times New Roman">}//while</FONT></P>
3 i1 ?- m/ G8 ^/ s2 Z<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>6 |) g4 S  |7 [) o2 P* K4 W2 s
<P ><FONT face="Times New Roman">}//if</FONT></P>
; @4 V$ s0 ^! ^3 _<P ><FONT face="Times New Roman">return –1;</FONT></P>* Q3 n! G8 i3 d& f9 _. ]- ~
<P ><FONT face="Times New Roman">}</FONT></P>
! E% ?1 E( t3 F<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
6 m0 I: \- _: b7 m& d<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>
* M& W4 d$ Y+ S! c) y<P ><FONT face="Times New Roman">public static int binarySearch7(int[] a, int x, int n)</FONT></P>; ~- P/ u# Z4 ]  H, x
<P ><FONT face="Times New Roman">{</FONT></P>4 M( {" y' f/ j
<P ><FONT face="Times New Roman">              if(n &gt; 0 &amp;&amp; x &gt;= a[0])</FONT></P>
  ~& A) p0 C& y4 ]& s<P ><FONT face="Times New Roman">              {</FONT></P>3 |# K( P- V9 n( ?
<P ><FONT face="Times New Roman">                     int left = 0, right = n-1;</FONT></P>7 ~9 m2 t+ ]) A! \( B
<P ><FONT face="Times New Roman">              while(left &lt; right)</FONT></P>% h- ~. C) ~" a
<P ><FONT face="Times New Roman">              {</FONT></P>
% Z4 `' N' U7 }8 H+ H0 |0 h1 o<P ><FONT face="Times New Roman">          int middle = (left + right +1) / 2;</FONT></P>
! z0 N2 i9 x0 d/ k$ E3 e<P ><FONT face="Times New Roman">if(x &lt; a[middle]) right = middle;</FONT></P>) k/ ^+ k: w2 e1 W
<P ><FONT face="Times New Roman">else left = middle;</FONT></P>
, w. U9 R8 T# A3 Y! k5 K<P ><FONT face="Times New Roman">}//while</FONT></P>
! k0 A5 p: m* ~) c<P ><FONT face="Times New Roman">if(x == a
) return left;</FONT></P>. t0 q2 C5 n) t3 ^4 {# O
<P ><FONT face="Times New Roman">}//if</FONT></P>
  C' w: B7 Z% G<P ><FONT face="Times New Roman">return –1;</FONT></P>8 h& i# U; T. A; f" @% O% Y- z9 Z
<P ><FONT face="Times New Roman">}</FONT></P>
0 p9 g" f7 {3 F7 C. T4 l<P ><FONT face="Times New Roman"> <o:p></o:p></FONT></P>  s# M" ?2 [$ R3 T" b& d: ^% E% O
<P >解:(<FONT face="Times New Roman">1</FONT>)算法<FONT face="Times New Roman">1</FONT>不正确。<o:p></o:p></P>* K) S. Y: E- a) I) Z: z6 x
<P >当在数组<FONT face="Times New Roman">a</FONT>中找不到与<FONT face="Times New Roman">x</FONT>相等的元素时,算法将进入死循环状态。<o:p></o:p></P>8 Z. V2 E8 b$ \7 e5 L" e6 {  K$ y
<P >原因:每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改不正确。应修改如下:<o:p></o:p></P>
; _# J% w- d8 b) E* q0 f<P ><FONT face="Times New Roman">if(x &gt; a[middle]) left = middle + 1;<o:p></o:p></FONT></P>
8 A: H8 Z( r0 z<P ><FONT face="Times New Roman">       else right = middle - 1;<o:p></o:p></FONT></P>: Z; R$ ?+ a4 w0 Y( [
<P >(<FONT face="Times New Roman">2</FONT>)算法<FONT face="Times New Roman">2</FONT>不正确。<o:p></o:p></P>
* \3 k. A" ^6 n5 A/ a- P1 ]! l1 [' C<P >当<FONT face="Times New Roman">n</FONT>≥<FONT face="Times New Roman">2</FONT>时,如果条件<FONT face="Times New Roman">x = a[n-1] </FONT>且<FONT face="Times New Roman"> a[n-2] </FONT>≠<FONT face="Times New Roman"> a[n-1]</FONT>成立,则必将在某一步之后出现<FONT face="Times New Roman">x = a[left +1]</FONT>,导致永远不会出现<FONT face="Times New Roman">x = a[middle]</FONT>的情形,算法最终在<FONT face="Times New Roman">x = a
</FONT>时结束循环,导致错误地返回<FONT face="Times New Roman">-1</FONT>。<o:p></o:p></P>
) b4 n- u7 Y7 I% E<P >另外,当<FONT face="Times New Roman">n=0</FONT>时执行<FONT face="Times New Roman">if(x == a
)...</FONT>时将出现下标越界错误。<o:p></o:p></P>
2 W' n* H8 b5 \4 u$ g<P >原因:循环结束条件错误,应改为<FONT face="Times New Roman">left &lt;= right</FONT>。每次循环时,变量<FONT face="Times New Roman">left</FONT>和<FONT face="Times New Roman">right</FONT>的值修改也不正确。<o:p></o:p></P>+ C( d+ N% A$ o/ O) m% g6 @5 E
<P >(<FONT face="Times New Roman">3</FONT>)算法<FONT face="Times New Roman">3</FONT>不正确。<o:p></o:p></P>
& I$ ~% k! M; j3 y  I" [<P >除了有与算法<FONT face="Times New Roman">2</FONT>相同的错误,另外当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,必然进入死循环。<o:p></o:p></P>' C1 `$ m; t% B! h6 O
<P >原因:与算法<FONT face="Times New Roman">2</FONT>相同。<o:p></o:p></P>
- M+ l) z! ~2 M5 v) ~<P >(<FONT face="Times New Roman">4</FONT>)算法<FONT face="Times New Roman">4</FONT>不正确。<o:p></o:p></P>/ |4 W0 ]" K! Q
<P >如果在循环过程中出现<FONT face="Times New Roman">left = right – 1</FONT>情况,算法即进入死循环。例如<FONT face="Times New Roman"> x</FONT>≥a[n-2]条件成立时,即必然进入死循环。<o:p></o:p></P>
! e& a$ ~+ x# O( D<P >原因:循环条件和对变量<FONT face="Times New Roman">left</FONT>值的修改有错误。<o:p></o:p></P>  N- E" c: H3 G, M/ k7 t- ?
<P >(<FONT face="Times New Roman">5</FONT>)此算法正确。<o:p></o:p></P>5 ~$ e$ Y. F: P* A
<P >证明:当<FONT face="Times New Roman">n=0</FONT>或<FONT face="Times New Roman">n=1</FONT>时,算法显然正确。<o:p></o:p></P>
8 {: O+ G; l' m- ~; s( L<P >当<FONT face="Times New Roman">n</FONT>≥<FONT face="Times New Roman">2</FONT>时,在循环结束前有<FONT face="Times New Roman">x</FONT>≥a[0]且left &lt; right,<o:p></o:p></P>
! ?3 O6 s6 i1 r$ W4 J<P >∴<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [left + (right –1) + 1 +1] / 2 </FONT>≥ (2left + 2) / 2 = left + 1,<o:p></o:p></P># y2 [) K, _6 v% E! B
<P >即:middle &gt; left成立。<o:p></o:p></P>
! ^. G, ^- N6 B* R<P >且<FONT face="Times New Roman">middle = (left + right + 1) / 2 = [(left + 1) + right] / 2 </FONT>≤ 2right / 2 = right,<o:p></o:p></P>* O" L7 H6 a5 Q6 \- B
<P >∴left &lt; middle ≤ right恒成立。<o:p></o:p></P>) ^! e% f# m& K+ C  W" W- t" c
<P >因此,每次循环之后,right与left之差必然减小,在有限次循环后,必有left = right条件成立,从而循环结束。<o:p></o:p></P>8 s. U% p3 ^; M6 y, [" N8 D
<P >如果x值与数组a的某个元素值相等,则在循环结束时显然有x = a
且x = a
成立,否则x ≠a
,即未找到x,<o:p></o:p></P>
0 I* i9 _. ~" i& D6 Z+ A- f<P >∴返回结果正确。<o:p></o:p></P>
+ f$ J* n* H, l0 H( W0 T<P >(6)算法6是错误的。<o:p></o:p></P>
9 B) E( ^" `, [; X- l2 I# O2 \<P >当执行到某次循环x = a[middle]成立时,再执行if 语句中的<o:p></o:p></P>
7 q3 R2 p! C4 `, h3 z5 E' u/ v<P >left = middle + 1;<o:p></o:p></P>& t! G7 J6 d4 Q' C& F) h
<P >就把结果丢失了,导致错误。而且还可能会导致下标越界错误。例如:<o:p></o:p></P>  K5 W- g" l' u+ S. x( b5 s, K! U
<P >当n = 2且x = a[1]时即会出现这些情况。<o:p></o:p></P>
  f! s) l3 \: v3 Y9 g; e<P >原因:if 语句中的left = middle + 1;应改为left = middle;<o:p></o:p></P>! m$ I! V7 W% o! t6 o
<P >(7)算法7是错误的。<o:p></o:p></P>
: S0 S' D9 W* y+ H<P >在循环过程中,一旦出现<o:p></o:p></P>, R8 c, J2 C1 S; W- H
<P >a
≤ x &lt; a[left + 1],则必进入死循环。<o:p></o:p></P>
8 {1 k2 F# s: \- q) V<P >原因:right值的修改不正确。<o:p></o:p></P>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-10-23 08:53 , Processed in 0.356299 second(s), 52 queries .

回顶部